Improve Batches
[aaf/authz.git] / auth / auth-batch / src / main / java / org / onap / aaf / auth / batch / update / Approvals.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  */
21
22 package org.onap.aaf.auth.batch.update;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.text.ParseException;
27 import java.util.ArrayList;
28 import java.util.Date;
29 import java.util.GregorianCalendar;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import java.util.TreeMap;
34
35 import org.onap.aaf.auth.batch.Batch;
36 import org.onap.aaf.auth.batch.BatchPrincipal;
37 import org.onap.aaf.auth.batch.approvalsets.ApprovalSet;
38 import org.onap.aaf.auth.batch.approvalsets.Pending;
39 import org.onap.aaf.auth.batch.approvalsets.URApprovalSet;
40 import org.onap.aaf.auth.batch.helpers.BatchDataView;
41 import org.onap.aaf.auth.batch.helpers.CQLBatch;
42 import org.onap.aaf.auth.batch.helpers.CQLBatchLoop;
43 import org.onap.aaf.auth.batch.helpers.LastNotified;
44 import org.onap.aaf.auth.batch.helpers.NS;
45 import org.onap.aaf.auth.batch.helpers.Notification;
46 import org.onap.aaf.auth.batch.helpers.Notification.TYPE;
47 import org.onap.aaf.auth.batch.helpers.Role;
48 import org.onap.aaf.auth.batch.helpers.UserRole;
49 import org.onap.aaf.auth.batch.reports.Notify;
50 import org.onap.aaf.auth.batch.reports.bodies.NotifyPendingApprBody;
51 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
52 import org.onap.aaf.auth.env.AuthzTrans;
53 import org.onap.aaf.auth.layer.Result;
54 import org.onap.aaf.auth.org.OrganizationException;
55 import org.onap.aaf.cadi.Access;
56 import org.onap.aaf.cadi.CadiException;
57 import org.onap.aaf.cadi.client.Holder;
58 import org.onap.aaf.cadi.util.CSV;
59 import org.onap.aaf.misc.env.APIException;
60 import org.onap.aaf.misc.env.TimeTaken;
61 import org.onap.aaf.misc.env.Trans;
62 import org.onap.aaf.misc.env.util.Chrono;
63
64 public class Approvals extends Batch {
65     private final Access access;
66         private final AuthzTrans noAvg;
67         private BatchDataView dataview;
68         private List<CSV> csvList;
69         private GregorianCalendar now;
70         private final Notify notify;
71         
72
73     public Approvals(AuthzTrans trans) throws APIException, IOException, OrganizationException {
74         super(trans.env());
75         notify = new Notify(trans);
76         access = env.access();
77         noAvg = env.newTransNoAvg();
78         noAvg.setUser(new BatchPrincipal("batch:Approvals"));
79         session = cluster.connect();
80         dataview = new BatchDataView(noAvg,session,dryRun);
81         NS.load(trans, session, NS.v2_0_11);
82         Role.load(trans, session);
83         UserRole.load(trans, session, UserRole.v2_0_11);
84
85         now = new GregorianCalendar();
86         
87         csvList = new ArrayList<>();
88         File f;
89         if(args().length>0) {
90                 for(int i=0;i<args().length;++i) {
91                         f = new File(logDir(), args()[i]);
92                         if(f.exists()) {
93                                 csvList.add(new CSV(env.access(),f).processAll());
94                         } else {
95                         trans.error().printf("CSV File %s does not exist",f.getAbsolutePath());
96                         }
97                 }
98         } else {
99                 f = new File(logDir(), "Approvals"+Chrono.dateOnlyStamp()+".csv");
100                 if(f.exists()) {
101                         csvList.add(new CSV(env.access(),f).processAll());
102                         } else {
103                         trans.error().printf("CSV File %s does not exist",f.getAbsolutePath());
104                         }
105         }
106     }
107
108     @Override
109     protected void run(AuthzTrans trans) {
110         Map<String,Pending> mpending = new TreeMap<>();
111                 Holder<Integer> count = new Holder<>(0);
112                 final CQLBatchLoop cbl = new CQLBatchLoop(new CQLBatch(noAvg.info(),session),100,dryRun);
113         for(CSV approveCSV : csvList) {
114                 TimeTaken tt = trans.start("Load Analyzed Reminders",Trans.SUB,approveCSV.name());
115                 try {
116                                 approveCSV.visit(row -> {
117                                         switch(row.get(0)) {
118                                                 case Pending.REMIND:
119                                                         try {
120                                                                 String user = row.get(1);
121                                                                 Pending p = new Pending(row);
122                                                                 Pending mp = mpending.get(user);
123                                                                 if(mp==null) {
124                                                                         mpending.put(user, p);
125                                                                 } else {
126                                                                         mp.inc(p); // FYI, unlikely
127                                                                 }
128                                                                 count.set(count.get()+1);
129                                                         } catch (ParseException e) {
130                                                                 trans.error().log(e);
131                                                         } 
132                                                 break;
133                                         }
134                                 });
135                         } catch (IOException | CadiException e) {
136                                 e.printStackTrace();
137                                 // .... but continue with next row
138                 } finally {
139                         tt.done();
140                 }
141         }
142         trans.info().printf("Processed %d Reminder Rows", count.get());
143
144         count.set(0);
145         for(CSV approveCSV : csvList) {
146                 TimeTaken tt = trans.start("Processing %s's UserRoles",Trans.SUB,approveCSV.name());
147                 try {
148                                 approveCSV.visit(row -> {
149                                         switch(row.get(0)) {
150                                                 case UserRole.APPROVE_UR:
151                                                         UserRoleDAO.Data urdd = UserRole.row(row);
152                                                         // Create an Approval
153                                                         ApprovalSet uras = new URApprovalSet(noAvg, now, dataview, () -> {
154                                                                 return urdd;
155                                                         });
156                                                         Result<Void> rw = uras.write(noAvg);
157                                                         if(rw.isOK()) {
158                                                                 Pending p = new Pending();
159                                                                 Pending mp = mpending.get(urdd.user);
160                                                                 if(mp==null) {
161                                                                         mpending.put(urdd.user, p);
162                                                                 } else {
163                                                                         mp.inc(p);
164                                                                 }
165                                                                 count.set(count.get()+1);
166                                                         } else {
167                                                                 trans.error().log(rw.errorString());
168                                                         }
169                                                         break;
170                                         }
171                                 });
172                                 dataview.flush();
173                         } catch (IOException | CadiException e) {
174                                 e.printStackTrace();
175                                 // .... but continue with next row
176                 } finally {
177                         tt.done();
178                 }
179             trans.info().printf("Processed %d UserRoles", count.get());
180
181             count.set(0);
182                 NotifyPendingApprBody npab = new NotifyPendingApprBody(access);
183
184                 GregorianCalendar gc = new GregorianCalendar();
185                 gc.add(GregorianCalendar.DAY_OF_MONTH, 7);
186                 Date oneWeek = gc.getTime();
187                 CSV.Saver rs = new CSV.Saver();
188                 
189                 tt = trans.start("Obtain Last Notifications", Trans.SUB);
190                 LastNotified lastN;
191                 try {
192                         lastN = new LastNotified(session);
193                         lastN.add(mpending.keySet());
194                 } finally {
195                         tt.done();
196                 }
197                 
198                 Pending p;
199                 tt = trans.start("Notify for Pending", Trans.SUB);
200                 try {
201                         for(Entry<String, Pending> es : mpending.entrySet()) {
202                                 p = es.getValue();
203                                 Date dateLastNotified = lastN.lastNotified(es.getKey());
204                                 if(p.newApprovals() || dateLastNotified==null || dateLastNotified.after(oneWeek) ) {
205                                         rs.row("appr", es.getKey(),p.qty(),batchEnv);
206                                         npab.store(rs.asList());
207                                         if(notify.notify(noAvg, npab)>0) {
208                                                 // Update
209                                                 cbl.preLoop();
210                                                 update(cbl.inc(),es.getKey(),Notification.TYPE.OA);
211                                         }
212                                 }
213                         }
214                 } finally {
215                         tt.done();
216                 }
217             trans.info().printf("Created %d Notifications", count.get());
218             }
219     }
220     
221     private void update(StringBuilder sb, String user, TYPE oa) {
222         sb.append("UPDATE authz.notify SET last=dateof(now()) WHERE user='");
223         sb.append(user);
224         sb.append("' AND type=");
225         sb.append(oa.idx());
226         sb.append(';');
227                 
228         }
229
230         @Override
231     protected void _close(AuthzTrans trans) {
232         if(session!=null) {
233                 session.close();
234                 session = null;
235         }
236     }
237 }