Batch work and client
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / reports / Notify.java
1 /**
2  * ============LICENSE_START====================================================
3  * org.onap.aaf
4  * ===========================================================================
5  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
6  * ===========================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END====================================================
19  *
20  */package org.onap.aaf.auth.batch.reports;
21
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.FileReader;
25  import java.io.IOException;
26  import java.lang.reflect.Constructor;
27  import java.lang.reflect.InvocationTargetException;
28  import java.util.ArrayList;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Set;
32
33  import org.onap.aaf.auth.batch.Batch;
34  import org.onap.aaf.auth.batch.reports.bodies.NotifyBody;
35  import org.onap.aaf.auth.env.AuthzTrans;
36  import org.onap.aaf.auth.org.Mailer;
37  import org.onap.aaf.auth.org.Organization.Identity;
38  import org.onap.aaf.auth.org.OrganizationException;
39  import org.onap.aaf.cadi.Access;
40  import org.onap.aaf.cadi.CadiException;
41  import org.onap.aaf.cadi.client.Holder;
42  import org.onap.aaf.cadi.util.CSV;
43  import org.onap.aaf.misc.env.APIException;
44  import org.onap.aaf.misc.env.util.Chrono;
45
46  public class Notify extends Batch {
47          private static final String HTML_CSS = "HTML_CSS";
48          private final Mailer mailer;
49          private final String header;
50          private final String footer;
51          private Set<File> notifyFile;
52          public final String guiURL;
53          private int maxEmails;
54          private int indent;
55
56          public Notify(AuthzTrans trans) throws APIException, IOException, OrganizationException {
57                  super(trans.env());
58                  String mailerCls = env.getProperty("MAILER");
59                  String mailFrom = env.getProperty("MAIL_FROM");
60                  String header_html = env.getProperty("HEADER_HTML");
61                  String footer_html = env.getProperty("FOOTER_HTML");
62                  String maxEmails = env.getProperty("MAX_EMAIL");
63                  guiURL = env.getProperty("GUI_URL");
64                  this.maxEmails = maxEmails==null?1:Integer.parseInt(maxEmails);
65                  if(mailerCls==null || mailFrom==null || guiURL==null || header_html==null || footer_html==null) {
66                          throw new APIException("Notify requires MAILER, MAILER_FROM, GUI_URL, HEADER_HTML and FOOTER_HTML properties");
67                  }
68                  try {
69                          Class<?> mailc = Class.forName(mailerCls);
70                          Constructor<?> mailcst = mailc.getConstructor(Access.class);
71                          mailer = (Mailer)mailcst.newInstance(env.access());
72                  } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
73                          throw new APIException("Unable to construct " + mailerCls,e);
74                  }
75
76                  String line;
77                  StringBuilder sb = new StringBuilder();
78                  BufferedReader br = new BufferedReader(new FileReader(header_html));
79                  try {
80                          while((line=br.readLine())!=null) {
81                                  sb.append(line);
82                                  sb.append('\n');
83                          }
84                          String html_css = env.getProperty(HTML_CSS);
85                          int hc = sb.indexOf(HTML_CSS);
86                          if(hc!=0 && html_css!=null) {
87                                  header = sb.replace(hc,hc+HTML_CSS.length(), html_css).toString();
88                          } else {
89                                  header = sb.toString();
90                          }
91                  } finally {
92                          br.close();
93                  }
94
95                  // Establish index from header
96                  int lastTag = header.lastIndexOf('<');
97                  if(lastTag>0) {
98                          int prevCR = header.lastIndexOf('\n',lastTag);
99                          if(prevCR>0) {
100                                  indent = lastTag-prevCR;
101                          } else {
102                                  indent = 6; //arbitrary
103                          }
104                  }
105
106
107                  sb.setLength(0);
108                  br = new BufferedReader(new FileReader(footer_html));
109                  try {
110                          while((line=br.readLine())!=null) {
111                                  sb.append(line);
112                                  sb.append('\n');
113                          }
114                          footer = sb.toString();
115                  } finally {
116                          br.close();
117                  }
118
119                  // Class Load possible data
120                  NotifyBody.load(env.access());
121
122                  // Create Intermediate Output 
123                  File logDir = logDir();
124                  notifyFile = new HashSet<>();
125                  if(args().length>0) {
126                          for(int i=0;i<args().length;++i) {
127                                  notifyFile.add(new File(logDir, args()[i]));
128                          }
129                  } else {
130                          String fmt = "%s"+Chrono.dateOnlyStamp()+".csv";
131                          File file;
132                          for(NotifyBody nb : NotifyBody.getAll()) {
133                                  file = new File(logDir,String.format(fmt, nb.name()));
134                                  if(file.exists()) {
135                                          trans.info().printf("Processing '%s' in %s",nb.type(),file.getCanonicalPath());
136                                          notifyFile.add(file);
137                                  } else {
138                                          trans.info().printf("No Files found for %s",nb.name());
139                                  }
140                          }
141                  }
142          }
143
144          @Override
145          protected void run(AuthzTrans trans) {
146                  List<String> toList = new ArrayList<>();
147                  List<String> ccList = new ArrayList<>();
148                  AuthzTrans noAvg = trans.env().newTransNoAvg();
149                  String subject = "Test Notify";
150                  boolean urgent = false;
151
152
153
154                  final Notify notify = this;
155                  final Holder<List<String>> info = new Holder<>(null);
156                  final Set<String> errorSet = new HashSet<>();
157
158                  try {
159                          for(File f : notifyFile) {
160                                  CSV csv = new CSV(env.access(),f);
161                                  try {
162                                          csv.visit(new CSV.Visitor() {
163                                                  @Override
164                                                  public void visit(List<String> row) throws IOException, CadiException {
165                                                          if("info".equals(row.get(0))) {
166                                                                  info.set(row);
167                                                          }
168                                                          if(info.get()==null) {
169                                                                  throw new CadiException("First line of Feed MUST contain 'info' record");
170                                                          }
171                                                          String key = row.get(0)+'|'+info.get().get(1);
172                                                          NotifyBody body = NotifyBody.get(key);
173                                                          if(body==null) {
174                                                                  errorSet.add("No NotifyBody defined for " + key);
175                                                          } else {
176                                                                  body.store(row);
177                                                          }
178                                                  }
179                                          });
180                                  } catch (IOException | CadiException e) {
181                                          e.printStackTrace();
182                                  }
183
184                          }      
185
186                          // now create Notification
187                          for(NotifyBody nb : NotifyBody.getAll()) {
188                                  String run = nb.type()+nb.name();
189                                  String test = dryRun?run:null;
190                                  ONE_EMAIL:
191                                          for(String id : nb.users()) {
192
193                                                  toList.clear();
194                                                  ccList.clear();
195                                                  try {
196                                                          Identity identity = trans.org().getIdentity(noAvg, id);
197                                                          if(identity==null) {
198                                                                  trans.warn().printf("%s is invalid for this Organization. Skipping notification.",id);
199                                                          } else {
200                                                                  if(!identity.isPerson()) {
201                                                                          identity = identity.responsibleTo();
202                                                                  }
203                                                                  for(int i=1;i<nb.escalation();++i) {
204                                                                          if(identity != null) {
205                                                                                  if(i==1) {
206                                                                                          toList.add(identity.email());
207                                                                                  } else {
208                                                                                          identity=identity.responsibleTo();
209                                                                                          ccList.add(identity.email());
210                                                                                  }
211                                                                          }
212                                                                  }
213
214                                                                  StringBuilder content = new StringBuilder();
215                                                                  content.append(String.format(header,version,Identity.mixedCase(identity.firstName())));
216
217                                                                  nb.body(noAvg, content, indent, notify, id);
218                                                                  content.append(footer);
219
220                                                                  if(mailer.sendEmail(noAvg, test, toList, ccList, subject,content.toString(), urgent)) {
221                                                                          nb.inc();
222                                                                  } else {
223                                                                          trans.error().log("Mailer failed to send Mail");
224                                                                  }
225                                                                  if(maxEmails>0 && nb.count()>=maxEmails) {
226                                                                          break ONE_EMAIL;
227                                                                  }
228                                                          }
229                                                  } catch (OrganizationException e) {
230                                                          trans.error().log(e);
231                                                  }
232                                          }
233                                  trans.info().printf("Emailed %d for %s",nb.count(),run);
234                          }
235
236
237                  } finally {
238                          for(String s : errorSet) {
239                                  trans.audit().log(s);
240                          }
241                  }
242          }
243
244          @Override
245          protected void _close(AuthzTrans trans) {
246          }
247
248  }