2 * ============LICENSE_START====================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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====================================================
22 package org.onap.aaf.auth.batch.update;
24 import java.io.BufferedReader;
26 import java.io.FileOutputStream;
27 import java.io.FileReader;
28 import java.io.IOException;
29 import java.io.PrintStream;
30 import java.util.Date;
31 import java.util.GregorianCalendar;
32 import java.util.List;
33 import java.util.UUID;
35 import org.onap.aaf.auth.batch.Batch;
36 import org.onap.aaf.auth.batch.BatchPrincipal;
37 import org.onap.aaf.auth.batch.actions.Action;
38 import org.onap.aaf.auth.batch.actions.ActionDAO;
39 import org.onap.aaf.auth.batch.actions.CacheTouch;
40 import org.onap.aaf.auth.batch.actions.CredDelete;
41 import org.onap.aaf.auth.batch.actions.CredPrint;
42 import org.onap.aaf.auth.batch.actions.Email;
43 import org.onap.aaf.auth.batch.actions.Message;
44 import org.onap.aaf.auth.batch.actions.URDelete;
45 import org.onap.aaf.auth.batch.actions.URFutureApprove;
46 import org.onap.aaf.auth.batch.actions.URFutureApproveExec;
47 import org.onap.aaf.auth.batch.actions.URPrint;
48 import org.onap.aaf.auth.batch.helpers.Approval;
49 import org.onap.aaf.auth.batch.helpers.Cred;
50 import org.onap.aaf.auth.batch.helpers.Future;
51 import org.onap.aaf.auth.batch.helpers.NS;
52 import org.onap.aaf.auth.batch.helpers.Role;
53 import org.onap.aaf.auth.batch.helpers.UserRole;
54 import org.onap.aaf.auth.batch.helpers.Cred.Instance;
55 import org.onap.aaf.auth.dao.cass.ApprovalDAO;
56 import org.onap.aaf.auth.dao.cass.CredDAO;
57 import org.onap.aaf.auth.dao.cass.FutureDAO;
58 import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
59 import org.onap.aaf.auth.dao.hl.Function.OP_STATUS;
60 import org.onap.aaf.auth.env.AuthzTrans;
61 import org.onap.aaf.auth.layer.Result;
62 import org.onap.aaf.auth.org.OrganizationException;
63 import org.onap.aaf.auth.org.Organization.Identity;
64 import org.onap.aaf.misc.env.APIException;
65 import org.onap.aaf.misc.env.Env;
66 import org.onap.aaf.misc.env.TimeTaken;
67 import org.onap.aaf.misc.env.util.Chrono;
69 public class ExpiringOrig extends Batch {
70 private CredPrint crPrint;
71 private URFutureApprove urFutureApprove;
72 private URFutureApproveExec urFutureApproveExec;
73 private CredDelete crDelete;
74 private URDelete urDelete;
75 private final CacheTouch cacheTouch;
76 private final AuthzTrans noAvg;
77 private final ApprovalDAO apprDAO;
78 private final FutureDAO futureDAO;
79 private final PrintStream urDeleteF,urRecoverF;
80 private final URPrint urPrint;
82 private File deletesFile;
84 public ExpiringOrig(AuthzTrans trans) throws APIException, IOException, OrganizationException {
86 trans.info().log("Starting Connection Process");
88 noAvg = env.newTransNoAvg();
89 noAvg.setUser(new BatchPrincipal("batch:Expiring"));
91 TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
93 crPrint = new CredPrint("Expired:");
95 TimeTaken tt = trans.start("Connect to Cluster with DAOs", Env.REMOTE);
97 urFutureApprove = new URFutureApprove(trans, cluster,isDryRun());
98 checkOrganizationAcccess(trans, urFutureApprove.question());
99 urFutureApproveExec = new URFutureApproveExec(trans, urFutureApprove);
100 urPrint = new URPrint("User Roles:");
101 crDelete = new CredDelete(trans, urFutureApprove);
102 urDelete = new URDelete(trans,urFutureApprove);
103 cacheTouch = new CacheTouch(trans, urFutureApprove);
105 // Reusing... don't destroy
106 apprDAO = urFutureApprove.question().approvalDAO;
107 futureDAO = urFutureApprove.question().futureDAO;
109 TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
111 session = urFutureApprove.getSession(trans);
119 File data_dir = new File(env.getProperty("aaf_data_dir"));
120 if (!data_dir.exists() || !data_dir.canWrite() || !data_dir.canRead()) {
121 throw new IOException("Cannot read/write to Data Directory "+ data_dir.getCanonicalPath() + ": EXITING!!!");
123 UserRole.setDeleteStream(
124 urDeleteF = new PrintStream(new FileOutputStream(deletesFile = new File(data_dir,"UserRoleDeletes.dat"),false)));
125 UserRole.setRecoverStream(
126 urRecoverF = new PrintStream(new FileOutputStream(new File(data_dir,"UserRoleRecover.dat"),false)));
127 UserRole.load(trans, session, UserRole.v2_0_11, new UserRole.DataLoadVisitor());
129 Cred.load(trans, session);
130 NS.load(trans, session,NS.v2_0_11);
131 Future.load(trans,session,Future.withConstruct);
132 Approval.load(trans,session,Approval.v2_0_17);
133 Role.load(trans, session);
136 email.subject("AAF Expiring Process Alert (ENV: %s)",batchEnv);
137 email.preamble("Expiring Process Alert for %s",batchEnv);
138 email.signature("Sincerely,\nAAF Expiring Batch Process\n");
139 String address = env.getProperty("ALERT_TO_ADDRESS");
141 throw new APIException("ALERT_TO_ADDRESS property is required");
143 email.addTo(address);
145 } catch (OrganizationException e) {
146 throw new APIException("Error getting valid Organization",e);
153 protected void run(AuthzTrans trans) {
154 // Setup Date boundaries
156 final GregorianCalendar gc = new GregorianCalendar();
157 final Date now = gc.getTime();
159 gc.add(GregorianCalendar.MONTH, 1);
160 Date future = gc.getTime();
161 // Date earliest = null;
165 gc.add(GregorianCalendar.DAY_OF_MONTH, -7); // save Expired Roles for 7 days.
166 Date tooLate = gc.getTime();
170 // Clean out Approvals UserRoles are fixed up.
172 for (List<Approval> la : Approval.byUser.values()) {
173 for (Approval a : la ) {
175 if (memo!=null && (memo.contains("Re-Approval") || memo.contains("Re-Validate"))) {
176 String role = a.getRole();
178 UserRole ur = UserRole.get(a.getUser(), a.getRole());
181 if (ur.expires().after(future)) { // no need for Approval anymore
182 a.delayDelete(noAvg, apprDAO, dryRun, "User Role already Extended");
183 UUID tkt = a.getTicket();
184 if (tkt!=null && Future.data.containsKey(tkt)) {
185 f = Future.data.get(a.getTicket());
189 a.delayDelete(noAvg, apprDAO, dryRun, "User Role does not exist");
190 UUID tkt = a.getTicket();
191 if (tkt !=null && Future.data.containsKey(tkt)) {
192 f = Future.data.get(a.getTicket());
196 f.delayedDelete(noAvg, futureDAO, dryRun, "Approvals removed");
203 trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
204 Future.resetLocalData();
205 Approval.resetLocalData();
206 } catch (Exception t) {
210 // Run for Expired Futures
211 trans.info().log("Checking for Expired Approval/Futures");
212 tt = trans.start("Delete old Futures", Env.REMOTE);
213 trans.info().log("### Running Future Execution on ",Future.data.size(), "Items");
214 // Execute any Futures waiting
215 for (Future f : Future.data.values()) {
216 if (f.memo().contains("Re-Approval") || f.memo().contains("Re-Validate")) {
217 List<Approval> la = Approval.byTicket.get(f.id());
219 Result<OP_STATUS> ruf = urFutureApproveExec.exec(noAvg,la,f);
227 f.delayedDelete(noAvg, futureDAO, dryRun,OP_STATUS.L.desc());
228 Approval.delayDelete(noAvg, apprDAO, dryRun, la,OP_STATUS.L.desc());
236 trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
237 Future.resetLocalData();
238 Approval.resetLocalData();
239 } catch (Exception t) {
244 trans.info().log("### Remove Expired on ",Future.data.size(), "Items, or premature ones");
246 String expiredBeforeNow = "Expired before " + tooLate;
247 String expiredAfterFuture = "Expired after " + future;
249 for (Future f : Future.data.values()) {
250 if (f.expires().before(tooLate)) {
251 f.delayedDelete(noAvg,futureDAO,dryRun, expiredBeforeNow);
252 Approval.delayDelete(noAvg, apprDAO, dryRun, Approval.byTicket.get(f.id()), expiredBeforeNow);
253 } else if (f.expires().after(future)) {
254 f.delayedDelete(noAvg,futureDAO,dryRun, expiredAfterFuture);
255 Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), expiredAfterFuture);
259 trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
260 Future.resetLocalData();
261 Approval.resetLocalData();
262 } catch (Exception t) {
269 trans.info().log("### Checking Approvals valid (",Approval.byApprover.size(),"Items)");
270 // Make sure users of Approvals are still valid
271 for (List<Approval> lapp : Approval.byTicket.values()) {
272 for (Approval app : lapp) {
274 if (app.getTicket()==null) {
277 f = Future.data.get(app.getTicket());
278 if (Future.pendingDelete(f)) {
283 if (f!=null && app.getRole()!=null && Role.byName.get(app.getRole())==null) {
284 f.delayedDelete(noAvg,futureDAO,dryRun,msg="Role '" + app.getRole() + "' no longer exists");
285 Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
289 switch(app.getStatus()) {
292 app.delayDelete(noAvg,apprDAO, isDryRun(), "ticketDeleted");
295 switch(app.getType()) {
297 boolean anOwner=false;
298 String approle = app.getRole();
300 Role role = Role.byName.get(approle);
302 app.delayDelete(noAvg, apprDAO, dryRun, "Role No Longer Exists");
305 // Make sure Owner Role exists
306 String owner = role.ns + ".owner";
307 if (Role.byName.containsKey(owner)) {
308 List<UserRole> lur = UserRole.getByRole().get(owner);
310 for (UserRole ur : lur) {
311 if (ur.user().equals(app.getApprover())) {
320 app.delayDelete(noAvg, apprDAO, dryRun, "No longer Owner");
327 Identity identity = org.getIdentity(noAvg, app.getUser());
328 if (identity==null) {
330 f.delayedDelete(noAvg,futureDAO,dryRun,msg = app.getUser() + " is no longer associated with " + org.getName());
331 Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
334 if (!app.getApprover().equals(identity.responsibleTo().fullID())) {
336 f.delayedDelete(noAvg,futureDAO,dryRun,msg = app.getApprover() + " is no longer a Supervisor of " + app.getUser());
337 Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
341 } catch (OrganizationException e) {
351 trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
352 Future.resetLocalData();
353 Approval.resetLocalData();
354 } catch (Exception t) {
358 int count = 0, deleted=0, delayedURDeletes = 0;
360 // Run for User Roles
361 trans.info().log("Checking for Expired User Roles");
363 for (UserRole ur : UserRole.getData()) {
364 if (org.getIdentity(noAvg, ur.user())==null) { // if not part of Organization;
365 if (isSpecial(ur.user())) {
366 trans.info().log(ur.user(),"is not part of organization, but may not be deleted");
368 ur.delayDelete(noAvg, "Not Part of Organization", dryRun);
373 if (NS.data.get(ur.ns())==null) {
374 ur.delayDelete(noAvg,"Namespace " + ur.ns() + " does not exist.",dryRun);
377 } else if (!Role.byName.containsKey(ur.role())) {
378 ur.delayDelete(noAvg,"Role " + ur.role() + " does not exist.",dryRun);
381 } else if (ur.expires().before(tooLate)) {
382 if ("owner".equals(ur.rname())) { // don't delete Owners, even if Expired
383 urPrint.exec(noAvg,ur,"Owner Expired (but not deleted)");
385 // In this case, when UR is expired, not dependent on other lookups, we delete straight out.
386 urDelete.exec(noAvg, ur,"Expired before " + tooLate);
389 //trans.logAuditTrail(trans.info());
390 } else if (ur.expires().before(future) && ur.expires().after(now)) {
392 // Is there an Approval set already
393 boolean needNew = true;
394 if (ur.role()!=null && ur.user()!=null) {
395 List<Approval> abm = Approval.byUser.get(ur.user());
397 for (Approval a : abm) {
398 if (a.getOperation().equals(FUTURE_OP.A.name()) && ur.role().equals(a.getRole())) {
399 if (Future.data.get(a.getTicket())!=null) {
408 urFutureApprove.exec(noAvg, ur,"");
413 } catch (OrganizationException e) {
414 env.info().log(e,"Exiting ...");
416 env.info().log("Found",count,"user roles expiring before",future);
417 env.info().log("deleting",deleted,"user roles expiring before",tooLate);
420 // Actualize UR Deletes, or send Email
421 if (UserRole.sizeForDeletion()>0) {
422 count+=UserRole.sizeForDeletion();
423 double onePercent = 0.01;
424 if (((double)UserRole.sizeForDeletion())/UserRole.getData().size() > onePercent) {
425 Message msg = new Message();
427 msg.line("Found %d of %d UserRoles marked for Deletion in file %s",
428 delayedURDeletes,UserRole.getData().size(),deletesFile.getCanonicalPath());
429 } catch (IOException e) {
430 msg.line("Found %d of %d UserRoles marked for Deletion.\n",
433 msg.line("Review the File. If data is ok, Use ExpiringP2 BatchProcess to complete the deletions");
436 email.exec(trans, org, "Email Support");
440 BufferedReader br = new BufferedReader(new FileReader(deletesFile));
442 ExpiringP2.deleteURs(noAvg, br, urDelete, null /* don't touch Cache here*/);
446 } catch (IOException io) {
447 noAvg.error().log(io);
452 String str = String.format("%d UserRoles modified or deleted", count);
453 cacheTouch.exec(trans, "user_role", str);
457 trans.info().log("Checking for Expired Credentials");
461 CredDAO.Data crd = new CredDAO.Data();
463 for ( Cred creds : Cred.data.values()) {
465 for (int type : creds.types()) {
467 for ( Instance inst : creds.instances) {
468 if (inst.expires.before(tooLate)) {
469 crd.expires = inst.expires;
470 crDelete.exec(noAvg, crd,"Expired before " + tooLate);
471 } else if (last==null || inst.expires.after(last)) {
476 if (last.before(future)) {
478 crPrint.exec(noAvg, crd,"");
485 String str = String.format("Found %d current creds expiring before %s", count, Chrono.dateOnlyStamp(future));
487 cacheTouch.exec(trans, "cred", str);
494 protected void _close(AuthzTrans trans) {
495 trans.info().log("End",this.getClass().getSimpleName(),"processing" );
496 for (Action<?,?,?> action : new Action<?,?,?>[] {crDelete}) {
497 if (action instanceof ActionDAO) {
498 ((ActionDAO<?,?,?>)action).close(trans);