From b24f7e097f17761a5c1b02c4dbfe6ee7d78836dd Mon Sep 17 00:00:00 2001 From: Instrumental Date: Sun, 10 Feb 2019 09:54:15 -0600 Subject: [PATCH] Add Cred Reporting Mailer Issue-ID: AAF-740,AAF-753,AAF-754 Change-Id: If2efc6ffbfa9897581ea00eb148fa61d793b058e Signed-off-by: Instrumental --- .../main/java/org/onap/aaf/auth/batch/Batch.java | 3 + .../aaf/auth/batch/approvalsets/URApprovalSet.java | 4 +- .../java/org/onap/aaf/auth/batch/helpers/Cred.java | 28 ++-- .../org/onap/aaf/auth/batch/reports/Notify.java | 69 ++++++++-- .../aaf/auth/batch/reports/bodies/AbsCredBody.java | 40 ------ .../aaf/auth/batch/reports/bodies/NotifyBody.java | 35 ++++- .../auth/batch/reports/bodies/NotifyCredBody.java | 76 +++++++++-- .../onap/aaf/auth/batch/helpers/test/JU_Cred.java | 2 +- .../batch/reports/bodies/JU_AbsCredBodyTest.java | 62 --------- auth/auth-cass/cass_init/init2_10.cql | 3 + auth/auth-cass/docker/dbash.sh | 28 ++++ .../java/org/onap/aaf/auth/org/FileMailer.java | 148 +++++++++++++++++++++ .../main/java/org/onap/aaf/auth/org/Mailer.java | 5 +- .../src/main/java/org/onap/aaf/org/DefaultOrg.java | 2 +- .../aaf/auth/service/facade/AuthzFacadeImpl.java | 2 +- .../src/main/java/org/onap/aaf/cadi/util/CSV.java | 4 +- 16 files changed, 363 insertions(+), 148 deletions(-) delete mode 100644 auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java delete mode 100644 auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/reports/bodies/JU_AbsCredBodyTest.java create mode 100644 auth/auth-cass/cass_init/init2_10.cql create mode 100644 auth/auth-cass/docker/dbash.sh create mode 100644 auth/auth-core/src/main/java/org/onap/aaf/auth/org/FileMailer.java diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java index 543564d9..1c65c058 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/Batch.java @@ -90,6 +90,7 @@ public abstract class Batch { public static final String GUI_URL="GUI_URL"; protected final Organization org; + protected String version; protected Batch(AuthzEnv env) throws APIException, IOException, OrganizationException { if (batchEnv != null) { @@ -143,6 +144,8 @@ public abstract class Batch { } } } + + version = env.getProperty(VERSION,Config.AAF_DEFAULT_API_VERSION); } protected abstract void run(AuthzTrans trans); diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java index b6767d4a..e1c75bf3 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java @@ -55,7 +55,7 @@ public class URApprovalSet extends ApprovalSet { } Result n = dv.ns(trans, urdd.ns); if(n.notOKorIsEmpty()) { - throw new CadiException(String.format("Namespace '%s' does not exist: %s", urdd.ns)); + throw new CadiException(String.format("Namespace '%s' does not exist: %s", urdd.ns,r.details)); } UserRoleDAO.Data found = null; Result> lur = dv.ursByRole(trans, urdd.role); @@ -68,7 +68,7 @@ public class URApprovalSet extends ApprovalSet { } } if(found==null) { - throw new CadiException(String.format("User '%s' in Role '%s' does not exist: %s", urdd.user,urdd.role)); + throw new CadiException(String.format("User '%s' in Role '%s' does not exist: %s", urdd.user,urdd.role,r.details)); } // Primarily, Owners are responsible, unless it's owned by self diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java index c4a9b0db..8a5dfea1 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Cred.java @@ -62,16 +62,23 @@ public class Cred { public final int type; public final Date expires,written; public final Integer other; + public final String tag; + public final Integer attn; + public final String notes; + - public Instance(int type, Date expires, Integer other, long written) { + public Instance(int type, Date expires, Integer other, long written, String tag, int attn, String notes) { this.type = type; this.expires = expires; this.other = other; this.written = new Date(written); + this.tag = tag; + this.attn = attn; + this.notes = notes; } public String toString() { - return expires.toString() + ": " + type; + return expires.toString() + ": " + type + ' ' + notes; } } @@ -107,12 +114,12 @@ public class Cred { } public static void load(Trans trans, Session session, int ... types ) { - load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred;",types); + load(trans, session,"select id, type, expires, other, writetime(cred), tag, attn, notes from authz.cred;",types); } public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) { - load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred WHERE ns='" + ns + "';"); + load(trans, session,"select id, type, expires, other, writetime(cred), tag, attn, notes from authz.cred WHERE ns='" + ns + "';"); } private static void load(Trans trans, Session session, String query, int ...types) { @@ -149,7 +156,8 @@ public class Cred { continue; } } - add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4)); + add(row.getString(0), row.getInt(1),row.getTimestamp(2),row.getInt(3),row.getLong(4), + row.getString(5),row.getInt(6),row.getString(7)); } } finally { tt.done(); @@ -164,14 +172,17 @@ public class Cred { final int type, final Date timestamp, final int other, - final long written + final long written, + final String tag, + final int attn, + final String notes ) { Cred cred = data.get(id); if (cred==null) { cred = new Cred(id); data.put(id, cred); } - cred.instances.add(new Instance(type, timestamp, other, written/1000)); + cred.instances.add(new Instance(type, timestamp, other, written/1000,tag,attn,notes)); List lscd = byNS.get(cred.ns); if (lscd==null) { @@ -277,7 +288,8 @@ public class Cred { } public void row(final CSV.Writer csvw, final Instance inst) { - csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires),inst.expires.getTime()); + csvw.row("cred",id,ns,Integer.toString(inst.type),Chrono.dateOnlyStamp(inst.expires), + inst.expires.getTime(),inst.tag,inst.attn,inst.notes); } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java index f8d98882..7fd26747 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java @@ -21,7 +21,6 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; @@ -42,22 +41,29 @@ import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.client.Holder; import org.onap.aaf.cadi.util.CSV; import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.util.Chrono; public class Notify extends Batch { + private static final String HTML_CSS = "HTML_CSS"; private final Mailer mailer; - private final String mailFrom; private final String header; private final String footer; private List notifyFile; + public final String guiURL; + private int maxEmails; + private int indent; public Notify(AuthzTrans trans) throws APIException, IOException, OrganizationException { super(trans.env()); String mailerCls = env.getProperty("MAILER"); - mailFrom = env.getProperty("MAIL_FROM"); + String mailFrom = env.getProperty("MAIL_FROM"); String header_html = env.getProperty("HEADER_HTML"); String footer_html = env.getProperty("FOOTER_HTML"); - if(mailerCls==null || mailFrom==null || header_html==null || footer_html==null) { - throw new APIException("Notify requires MAILER, MAILER_FROM, HEADER_HTML and FOOTER_HTML properties"); + String maxEmails = env.getProperty("MAX_EMAIL"); + guiURL = env.getProperty("GUI_URL"); + this.maxEmails = maxEmails==null?1:Integer.parseInt(maxEmails); + if(mailerCls==null || mailFrom==null || guiURL==null || header_html==null || footer_html==null) { + throw new APIException("Notify requires MAILER, MAILER_FROM, GUI_URL, HEADER_HTML and FOOTER_HTML properties"); } try { Class mailc = Class.forName(mailerCls); @@ -75,11 +81,32 @@ public class Notify extends Batch { sb.append(line); sb.append('\n'); } - header = sb.toString(); + String html_css = env.getProperty(HTML_CSS); + int hc = sb.indexOf(HTML_CSS); + if(hc!=0 && html_css!=null) { + header = sb.replace(hc,hc+HTML_CSS.length(), html_css).toString(); + } else { + header = sb.toString(); + } } finally { br.close(); } + + + // Establish index from header + int lastTag = header.lastIndexOf('<'); + if(lastTag>0) { + int prevCR = header.lastIndexOf('\n',lastTag); + if(prevCR>0) { + indent = lastTag-prevCR; + } else { + indent = 6; //arbitrary + } + } + + + sb.setLength(0); br = new BufferedReader(new FileReader(footer_html)); try { while((line=br.readLine())!=null) { @@ -101,6 +128,18 @@ public class Notify extends Batch { for(int i=0;i errorSet = new HashSet<>(); try { + EMAILTYPE: for(File f : notifyFile) { CSV csv = new CSV(env.access(),f); try { @@ -150,7 +190,6 @@ public class Notify extends Batch { toList.clear(); ccList.clear(); try { - String bodyS = nb.body(noAvg, notify, id); Identity identity = trans.org().getIdentity(noAvg, id); if(!identity.isPerson()) { identity = identity.responsibleTo(); @@ -165,11 +204,19 @@ public class Notify extends Batch { } } } + + StringBuilder content = new StringBuilder(); + content.append(String.format(header,version,Identity.mixedCase(identity.firstName()))); + + nb.body(noAvg, content, indent, notify, id); + content.append(footer); - mailer.sendEmail(noAvg, dryRun, mailFrom, toList, ccList, subject, - String.format(header,"2.1.9",Identity.mixedCase(identity.firstName()))+ - bodyS + - footer, urgent); + if(!mailer.sendEmail(noAvg, dryRun, toList, ccList, subject,content.toString(), urgent)) { + trans.error().log("Mailer failed to send Mail"); + } + if(maxEmails>0 && mailer.count()>=maxEmails) { + break EMAILTYPE; + } } catch (OrganizationException e) { trans.error().log(e); } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java deleted file mode 100644 index 6dd5bb25..00000000 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/AbsCredBody.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * ============LICENSE_START==================================================== - * org.onap.aaf - * =========================================================================== - * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. - * - * Modifications Copyright (C) 2018 IBM. - * =========================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END==================================================== - * - */ -package org.onap.aaf.auth.batch.reports.bodies; - -import java.util.List; - -public abstract class AbsCredBody extends NotifyBody { - - public AbsCredBody(final String name) { - super("cred",name); - } - - @Override - public String user(List row) { - if( (row != null) && row.size()>1) { - return row.get(1); - } - return null; - } -} diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java index 429ea6d2..453c2f2f 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyBody.java @@ -30,6 +30,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,6 +42,7 @@ import org.onap.aaf.cadi.Access; import org.onap.aaf.misc.env.APIException; public abstract class NotifyBody { + private static final String DUPL = "''"; private static final Map bodyMap = new HashMap<>(); protected Map>> rows; @@ -105,7 +107,7 @@ public abstract class NotifyBody { * @param row * @return */ - public abstract String body(AuthzTrans trans, Notify n, String id); + public abstract boolean body(AuthzTrans trans, StringBuilder sb, int indent, Notify n, String id); /** * Return "null" if user not found in row... Code will handle. @@ -127,7 +129,11 @@ public abstract class NotifyBody { * */ public static Collection getAll() { - return bodyMap.values(); + // Note: The same Notify Body is entered several times with different keys. + // Therefore, need a Set of Values, not all the Values. + Set set = new HashSet<>(); + set.addAll(bodyMap.values()); + return set; } /** @@ -140,14 +146,10 @@ public abstract class NotifyBody { ClassLoader cl = Thread.currentThread().getContextClassLoader(); Package pkg = NotifyBody.class.getPackage(); String path = pkg.getName().replace('.', '/'); -// Enumeration urls = cl.getResources(path); -// while(urls.hasMoreElements()) { -// URL url = urls.nextElement(); URL url = cl.getResource(path); if(url == null) { throw new APIException("Cannot load resources from " + path); } - System.out.println(url); File dir; try { dir = new File(url.toURI()); @@ -180,6 +182,25 @@ public abstract class NotifyBody { } } } -// } } + + + protected void println(StringBuilder sb, int indent, Object ... objs) { + for(int i=0;i",current,""); + } + } + } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java index db96d50a..2369582d 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyCredBody.java @@ -27,10 +27,11 @@ import org.onap.aaf.auth.batch.reports.Notify; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.cadi.Access; -public class NotifyCredBody extends AbsCredBody { +public abstract class NotifyCredBody extends NotifyBody { + private final String explanation; public NotifyCredBody(Access access, String name) throws IOException { - super(name); + super("cred",name); // Default explanation = "The following Credentials are expiring on the dates shown. " @@ -38,17 +39,70 @@ public class NotifyCredBody extends AbsCredBody { } @Override - public String body(AuthzTrans trans, Notify n, String id) { - StringBuilder sb = new StringBuilder(); - sb.append(explanation); - sb.append("
"); - sb.append("\n" + - "Role\n" + - "Expires\n" + - "\n"); + public boolean body(AuthzTrans trans, StringBuilder sb, int indent, Notify n, String id) { + println(sb,indent,explanation); + println(sb,indent,"

"); + println(sb,indent,""); + indent+=2; + println(sb,indent,""); + indent+=2; + println(sb,indent,""); + println(sb,indent,""); + println(sb,indent,""); + println(sb,indent,""); + println(sb,indent,""); + indent-=2; + println(sb,indent,""); + String theid, type, info, gui, expires, notes; + String p_theid=null, p_type=null, p_gui=null, p_expires=null; for(List row : rows.get(id)) { + theid=row.get(1); + switch(row.get(3)) { + case "1": + case "2": + type = "Password"; + case "200": + type = "x509 (Certificate)"; + break; + default: + type = "Unknown, see AAF GUI"; + break; + } + gui = ""+row.get(2)+""; + expires = row.get(4); + info = row.get(6); + notes = row.get(8); + if(notes!=null && !notes.isEmpty()) { + info += "
" + notes; + } + println(sb,indent,"
"); + indent+=2; + printCell(sb,indent,theid,p_theid); + printCell(sb,indent,type,p_type); + printCell(sb,indent,info,null); + printCell(sb,indent,expires,p_expires); + printCell(sb,indent,gui,p_gui); + indent-=2; + println(sb,indent,""); + p_theid=theid; + p_type=type; + p_gui=gui; + p_expires=expires; + } + indent-=2; + println(sb,indent,"
Fully Qualified IDTypeDetailsExpiresCred Detail Page
"); + + return true; + } + + @Override + public String user(List row) { + if( (row != null) && row.size()>1) { + return row.get(1); } - return sb.toString(); + return null; } + + } diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Cred.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Cred.java index 20831c66..4861696b 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Cred.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Cred.java @@ -79,7 +79,7 @@ public class JU_Cred { prop.setProperty(Config.AAF_ROOT_COMPANY,"test"); define.set(prop); - instance = new Instance(12, date, integer, 125642678910L); + instance = new Instance(12, date, integer, 125642678910L,"234",1,""); cred = new Cred("myid1234@aaf.att.com"); } diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/reports/bodies/JU_AbsCredBodyTest.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/reports/bodies/JU_AbsCredBodyTest.java deleted file mode 100644 index e7d226b1..00000000 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/reports/bodies/JU_AbsCredBodyTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * ============LICENSE_START==================================================== - * org.onap.aaf - * =========================================================================== - * Copyright (c) 2019 IBM Intellectual Property. All rights reserved. - * =========================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END==================================================== - * - */ - - -package org.onap.aaf.auth.batch.reports.bodies; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.junit.Assert; -import org.junit.Test; -import org.onap.aaf.auth.batch.reports.Notify; -import org.onap.aaf.auth.env.AuthzTrans; - -public class JU_AbsCredBodyTest { - - @Test - public void testUserWithValue() { - List row = new ArrayList<>(); - row.add("test"); - row.add("user"); - AbsCredBody absCredBody = new AbsCredBody("") { - @Override - public String body(AuthzTrans trans, Notify n, String id) { - return null; - } - }; - Assert.assertEquals("user", absCredBody.user(row)); - } - - @Test - public void testUserWithoutValue() { - //String testStr = "test"; - List row = Collections.emptyList(); - AbsCredBody absCredBody = new AbsCredBody("") { - @Override - public String body(AuthzTrans trans, Notify n, String id) { - return null; - } - }; - Assert.assertNull(absCredBody.user(row)); - } -} \ No newline at end of file diff --git a/auth/auth-cass/cass_init/init2_10.cql b/auth/auth-cass/cass_init/init2_10.cql new file mode 100644 index 00000000..8536c03e --- /dev/null +++ b/auth/auth-cass/cass_init/init2_10.cql @@ -0,0 +1,3 @@ +use authz; +alter TABLE cred ADD tag varchar; +alter TABLE cred ADD attn int; diff --git a/auth/auth-cass/docker/dbash.sh b/auth/auth-cass/docker/dbash.sh new file mode 100644 index 00000000..1e13d27d --- /dev/null +++ b/auth/auth-cass/docker/dbash.sh @@ -0,0 +1,28 @@ +#!/bin/bash +######### +# ============LICENSE_START==================================================== +# org.onap.aaf +# =========================================================================== +# Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +# =========================================================================== +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END==================================================== +# +# Pull in AAF Env Variables from AAF install +if [ -e ../../docker/d.props ]; then + . ../../docker/d.props +fi +DOCKER=${DOCKER:-docker} + +$DOCKER exec -it aaf_cass bash + diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/FileMailer.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/FileMailer.java new file mode 100644 index 00000000..e5fc4387 --- /dev/null +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/FileMailer.java @@ -0,0 +1,148 @@ +/** + * ============LICENSE_START==================================================== + * org.onap.aaf + * =========================================================================== + * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. + * =========================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END==================================================== + * + */ +package org.onap.aaf.auth.org; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.cadi.Access; +import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.util.Chrono; + +public class FileMailer implements Mailer { + private Path dir; + private String mail_from; + private String testName; + private int count; + + + public FileMailer(Access access) throws APIException { + count = 0; + + mail_from = access.getProperty("MAIL_FROM", null); + if(mail_from==null) { + throw new APIException("MAIL_FROM property is required for Email Notifications"); + } + String env = access.getProperty("CASS_ENV", "UNKNOWN"); + String logdir = access.getProperty(env+".LOG_DIR", "logs/"+env); + dir = Paths.get(logdir+"/email/"+Chrono.dateOnlyStamp()); + if(!Files.exists(dir)) { + try { + Files.createDirectories(dir); + } catch (IOException e) { + throw new APIException("Cannot create directory: " + dir.toString(),e); + } + } + + boolean dryrun = Boolean.parseBoolean(access.getProperty("DRY_RUN","false")); + int maxEmail = Integer.parseInt(access.getProperty("MAX_EMAIL", "-1")); + if(dryrun && maxEmail==1) { + testName = "email_test"; + } else { + testName = null; + } + } + + @Override + public boolean sendEmail(AuthzTrans trans, boolean testMode, List toList, List ccList, + String subject, String body, Boolean urgent) throws OrganizationException { + boolean status = false; + try { + Path path; + if(testName==null) { + path = Files.createTempFile(dir, "email", ".hdr"); + } else { + path = Paths.get(dir.toString(), "emailTEST.hdr"); + } + BufferedWriter bw = Files.newBufferedWriter(path); + try { + bw.write("TO: "); + boolean first = true; + for(String to : toList) { + if(first) { + first = false; + } else { + bw.write(','); + } + bw.write(to); + } + bw.newLine(); + + bw.write("CC: "); + first = true; + for(String cc : ccList) { + if(first) { + first = false; + } else { + bw.write(','); + } + bw.write(cc); + } + bw.newLine(); + + bw.write("FROM: "); + bw.write(mail_from); + bw.newLine(); + + bw.write("SUBJECT: "); + bw.write(subject); + bw.newLine(); + + if(urgent) { + bw.write("Importance: High"); + bw.newLine(); + } + + } finally { + bw.close(); + } + + path = Paths.get(path.toString().replaceAll(".hdr", ".html")); + bw = Files.newBufferedWriter(path); + try { + bw.write(body); + bw.newLine(); + } finally { + bw.close(); + } + status = true; + } catch ( IOException e) { + throw new OrganizationException(e); + } + ++count; + return status; + } + + @Override + public String mailFrom() { + return mail_from; + } + + @Override + public int count() { + return count; + } +} diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Mailer.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Mailer.java index 1f1c28b8..f7c8b480 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Mailer.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Mailer.java @@ -25,10 +25,9 @@ import java.util.List; import org.onap.aaf.auth.env.AuthzTrans; public interface Mailer { - public int sendEmail( + public boolean sendEmail( AuthzTrans trans, boolean testMode, - String mailFrom, List toList, List ccList, String subject, @@ -37,4 +36,6 @@ public interface Mailer { public String mailFrom(); + public int count(); + } diff --git a/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java b/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java index c7dd3d33..f1932a26 100644 --- a/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java +++ b/auth/auth-deforg/src/main/java/org/onap/aaf/org/DefaultOrg.java @@ -592,7 +592,7 @@ public class DefaultOrg implements Organization { } } - return mailer.sendEmail(trans,dryRun,mailFrom,to,cc,subject,body,urgent); + return mailer.sendEmail(trans,dryRun,to,cc,subject,body,urgent)?0:1; } else { return 0; } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java index 1cc88250..e77e0908 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java @@ -282,7 +282,7 @@ public abstract class AuthzFacadeImpl row = new ArrayList<>(); boolean quotes=false; boolean escape=false; - char c; + char c = 0; for(int i=0;i0) { + if(sb.length()>0 || c==',') { row.add(sb.toString()); sb.setLength(0); } -- 2.16.6