diff options
author | Instrumental <jonathan.gathman@att.com> | 2019-03-07 12:58:39 -0600 |
---|---|---|
committer | Instrumental <jonathan.gathman@att.com> | 2019-03-07 12:58:54 -0600 |
commit | a174f8ddbc5eb78a648fb68b33ef18cb64d81fda (patch) | |
tree | d27c01bcd63fd6a7bff00687c6f33423a3a40e8c | |
parent | 9dc1cd2632d1dda9c8f072e99616e73e0517f1aa (diff) |
Improve Batches
Issue-ID: AAF-740
Change-Id: Ib3e8a3f977964eed2e992dc02154dd3bc90492df
Signed-off-by: Instrumental <jonathan.gathman@att.com>
48 files changed, 958 insertions, 543 deletions
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Pending.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Pending.java index 2e7997b4..3072038a 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Pending.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Pending.java @@ -105,4 +105,5 @@ public class Pending { public boolean newApprovals() { return hasNew; } + }
\ No newline at end of file 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 858690ac..2c1ffe6d 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 @@ -21,6 +21,7 @@ package org.onap.aaf.auth.batch.approvalsets; import java.io.IOException; +import java.util.Date; import java.util.GregorianCalendar; import java.util.List; @@ -40,7 +41,7 @@ import org.onap.aaf.misc.env.util.Chrono; public class URApprovalSet extends ApprovalSet { - private boolean ownerSuperApprove; + private boolean ownerSuperApprove = true; public URApprovalSet(final AuthzTrans trans, final GregorianCalendar start, final DataView dv, final Loader<UserRoleDAO.Data> lurdd) throws IOException, CadiException { super(start, "user_role", dv); @@ -49,6 +50,8 @@ public class URApprovalSet extends ApprovalSet { setConstruct(urdd.bytify()); setMemo(getMemo(urdd)); setExpires(org.expiration(null, Organization.Expiration.UserInRole)); + setTargetKey(urdd.role); + setTargetDate(urdd.expires); Result<RoleDAO.Data> r = dv.roleByName(trans, urdd.role); if(r.notOKorIsEmpty()) { @@ -88,18 +91,13 @@ public class URApprovalSet extends ApprovalSet { } } - if(isOwner && ownerSuperApprove) { + if(isOwner) { try { List<Identity> apprs = org.getApprovers(trans, urdd.user); if(apprs!=null) { for(Identity i : apprs) { ApprovalDAO.Data add = newApproval(urdd); - Identity reportsTo = i.responsibleTo(); - if(reportsTo!=null) { - add.approver = reportsTo.fullID(); - } else { - throw new CadiException("No Supervisor for '" + urdd.user + '\''); - } + add.approver = i.fullID(); add.type = org.getApproverType(); ladd.add(add); } @@ -110,8 +108,16 @@ public class URApprovalSet extends ApprovalSet { } } - public void ownerSuperApprove() { - ownerSuperApprove = true; + private void setTargetDate(Date expires) { + fdd.target_date = expires; + } + + private void setTargetKey(String key) { + fdd.target_key = key; + } + + public void ownerSuperApprove(boolean set) { + ownerSuperApprove = set; } private ApprovalDAO.Data newApproval(UserRoleDAO.Data urdd) throws CadiException { diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Approval.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Approval.java index 2cc6907b..1bc82f5e 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Approval.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Approval.java @@ -57,13 +57,13 @@ public class Approval implements CacheChange.Data { public final ApprovalDAO.Data add; private String role; - public Approval(UUID id, UUID ticket, String approver, Date last_notified, + public Approval(UUID id, UUID ticket, String approver,// Date last_notified, String user, String memo, String operation, String status, String type, long updated) { add = new ApprovalDAO.Data(); add.id = id; add.ticket = ticket; add.approver = approver; - add.last_notified = last_notified; +// add.last_notified = last_notified; add.user = user; add.memo = memo; add.operation = operation; @@ -125,8 +125,8 @@ public class Approval implements CacheChange.Data { } } - public static void row(CSV.Writer cw, Approval app) { - cw.row("approval",app.add.id,app.add.ticket,app.add.user,app.role,app.add.memo); + public static void row(CSV.RowSetter crs, Approval app) { + crs.row("approval",app.add.id,app.add.ticket,app.add.user,app.role,app.add.memo); } @@ -211,41 +211,41 @@ public class Approval implements CacheChange.Data { } } - public void update(AuthzTrans trans, ApprovalDAO apprDAO, boolean dryRun) { - if (dryRun) { - trans.info().printf("Would update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified); - } else { - trans.info().printf("Update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified); - apprDAO.update(trans, add); - } - } +// public void update(AuthzTrans trans, ApprovalDAO apprDAO, boolean dryRun) { +// if (dryRun) { +// trans.info().printf("Would update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified); +// } else { +// trans.info().printf("Update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified); +// apprDAO.update(trans, add); +// } +// } public static Creator<Approval> v2_0_17 = new Creator<Approval>() { @Override public Approval create(Row row) { - return new Approval(row.getUUID(0), row.getUUID(1), row.getString(2), row.getTimestamp(3), - row.getString(4),row.getString(5),row.getString(6),row.getString(7),row.getString(8) - ,row.getLong(9)/1000); + return new Approval(row.getUUID(0), row.getUUID(1), row.getString(2), + row.getString(3),row.getString(4),row.getString(5),row.getString(6),row.getString(7), + row.getLong(8)/1000); } @Override public String select() { - return "select id,ticket,approver,last_notified,user,memo,operation,status,type,WRITETIME(status) from authz.approval"; + return "select id,ticket,approver,user,memo,operation,status,type,WRITETIME(status) from authz.approval"; } }; - /** - * @return the lastNotified - */ - public Date getLast_notified() { - return add.last_notified; - } - /** - * @param lastNotified the lastNotified to set - */ - public void setLastNotified(Date last_notified) { - add.last_notified = last_notified; - } +// /** +// * @return the lastNotified +// */ +// public Date getLast_notified() { +// return add.last_notified; +// } +// /** +// * @param lastNotified the lastNotified to set +// */ +// public void setLastNotified(Date last_notified) { +// add.last_notified = last_notified; +// } /** * @return the status */ diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/BatchDataView.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/BatchDataView.java index 37def6d6..83945ee6 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/BatchDataView.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/BatchDataView.java @@ -134,12 +134,12 @@ public class BatchDataView implements DataView { public Result<ApprovalDAO.Data> insert(AuthzTrans trans, ApprovalDAO.Data add) { cqlBatch.preLoop(); StringBuilder sb = cqlBatch.inc(); - sb.append("INSERT INTO authz.approval (id,approver,last_notified,memo,operation,status,ticket,type,user) VALUES ("); + sb.append("INSERT INTO authz.approval (id,approver,memo,operation,status,ticket,type,user) VALUES ("); sb.append(add.id.toString()); sb.append(COMMA_QUOTE); sb.append(add.approver); - sb.append(QUOTE_COMMA_QUOTE); - sb.append(Chrono.utcStamp(add.last_notified)); +// sb.append(QUOTE_COMMA_QUOTE); +// sb.append(Chrono.utcStamp(add.last_notified)); sb.append(QUOTE_COMMA_QUOTE); sb.append(add.memo.replace("'", "''")); sb.append(QUOTE_COMMA_QUOTE); @@ -160,7 +160,7 @@ public class BatchDataView implements DataView { public Result<FutureDAO.Data> insert(AuthzTrans trans, FutureDAO.Data fdd) { cqlBatch.preLoop(); StringBuilder sb = cqlBatch.inc(); - sb.append("INSERT INTO authz.future (id,construct,expires,memo,start,target) VALUES ("); + sb.append("INSERT INTO authz.future (id,construct,expires,memo,start,target,target_key,target_date) VALUES ("); sb.append(fdd.id.toString()); sb.append(','); fdd.construct.hasArray(); @@ -173,6 +173,14 @@ public class BatchDataView implements DataView { sb.append(Chrono.utcStamp(fdd.expires)); sb.append(QUOTE_COMMA_QUOTE); sb.append(fdd.target); + if(fdd.target_key==null) { + sb.append("',,'"); + } else { + sb.append(QUOTE_COMMA_QUOTE); + sb.append(fdd.target_key==null?"":fdd.target_key); + sb.append(QUOTE_COMMA_QUOTE); + } + sb.append(Chrono.utcStamp(fdd.target_date)); sb.append(QUOTE_PAREN_SEMI); return Result.ok(fdd); } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/LastNotified.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/LastNotified.java new file mode 100644 index 00000000..22231f3a --- /dev/null +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/LastNotified.java @@ -0,0 +1,90 @@ +/** + * ============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.helpers; + +import java.util.Date; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +import org.onap.aaf.auth.batch.helpers.Notification.TYPE; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; + +public class LastNotified { + private Map<String,Date> lastNotified = new TreeMap<>(); + private Session session; + + public LastNotified(Session session) { + this.session = session; + } + + public void add(Set<String> users) { + StringBuilder query = new StringBuilder(); + startNotifyQuery(query); + int cnt = 0; + for(String user : users) { + if(++cnt>1) { + query.append(','); + } + query.append('\''); + query.append(user); + query.append('\''); + if(cnt>=30) { + endNotifyQuery(query, Notification.TYPE.OA); + add(session.execute(query.toString()),lastNotified); + query.setLength(0); + startNotifyQuery(query); + cnt=0; + } + } + if(cnt>0) { + endNotifyQuery(query, Notification.TYPE.OA); + add(session.execute(query.toString()),lastNotified); + } + } + + public Date lastNotified(String user) { + return lastNotified.get(user); + } + + private void add(ResultSet result, Map<String, Date> lastNotified) { + for(Iterator<Row> iter = result.iterator(); iter.hasNext();) { + Row r = iter.next(); + lastNotified.put(r.getString(0), r.getTimestamp(1)); + } + } + + private void startNotifyQuery(StringBuilder query) { + query.append("SELECT user,last FROM authz.notify WHERE user in ("); + } + + private void endNotifyQuery(StringBuilder query, TYPE oa) { + query.append(") AND type="); + query.append(oa.idx()); + query.append(';'); + } +} diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Analyze.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Analyze.java index 35020836..a0dce749 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Analyze.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Analyze.java @@ -231,7 +231,7 @@ public class Analyze extends Batch { ++state[type][pending]; Pending n = pendingTemp.get(appr.getApprover()); if(n==null) { - pendingTemp.put(appr.getApprover(),new Pending(appr.getLast_notified())); + pendingTemp.put(appr.getApprover(),new Pending()); } else { n.inc(); } @@ -288,7 +288,7 @@ public class Analyze extends Batch { for(Entry<String, Pending> es : pendingApprs.entrySet()) { Pending p = es.getValue(); - if(p.earliest() == null || p.earliest().after(remind)) { + if(p.newApprovals() || p.earliest() == null || p.earliest().after(remind)) { p.row(approveCW,es.getKey()); } } 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 0524c5cb..1c1f660c 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 @@ -20,38 +20,38 @@ */package org.onap.aaf.auth.batch.reports; import java.io.BufferedReader; - import java.io.File; - import java.io.FileReader; - import java.io.IOException; - import java.lang.reflect.Constructor; - import java.lang.reflect.InvocationTargetException; - import java.util.ArrayList; - import java.util.HashSet; - import java.util.List; - import java.util.Set; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; - import org.onap.aaf.auth.batch.Batch; - import org.onap.aaf.auth.batch.reports.bodies.NotifyBody; - import org.onap.aaf.auth.env.AuthzTrans; - import org.onap.aaf.auth.org.Mailer; - import org.onap.aaf.auth.org.Organization.Identity; - import org.onap.aaf.auth.org.OrganizationException; - import org.onap.aaf.cadi.Access; - 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; +import org.onap.aaf.auth.batch.Batch; +import org.onap.aaf.auth.batch.reports.bodies.NotifyBody; +import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.auth.org.Mailer; +import org.onap.aaf.auth.org.Organization.Identity; +import org.onap.aaf.auth.org.OrganizationException; +import org.onap.aaf.cadi.Access; +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 header; private final String footer; - private Set<File> notifyFile; + private final int maxEmails; + private final int indent; + private final boolean urgent; public final String guiURL; - private int maxEmails; - private int indent; public Notify(AuthzTrans trans) throws APIException, IOException, OrganizationException { super(trans.env()); @@ -59,9 +59,9 @@ String mailFrom = env.getProperty("MAIL_FROM"); String header_html = env.getProperty("HEADER_HTML"); String footer_html = env.getProperty("FOOTER_HTML"); - String maxEmails = env.getProperty("MAX_EMAIL"); + String str = env.getProperty("MAX_EMAIL"); guiURL = env.getProperty("GUI_URL"); - this.maxEmails = maxEmails==null?1:Integer.parseInt(maxEmails); + maxEmails = str==null||str.isEmpty()?Integer.MAX_VALUE:Integer.parseInt(str); 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"); } @@ -101,9 +101,12 @@ } else { indent = 6; //arbitrary } + } else { + indent = 6; } - + urgent = false; + sb.setLength(0); br = new BufferedReader(new FileReader(footer_html)); try { @@ -116,46 +119,45 @@ br.close(); } - // Class Load possible data - NotifyBody.load(env.access()); - - // Create Intermediate Output - File logDir = logDir(); - notifyFile = new HashSet<>(); - if(args().length>0) { - for(int i=0;i<args().length;++i) { - notifyFile.add(new File(logDir, args()[i])); - } - } else { - String fmt = "%s"+Chrono.dateOnlyStamp()+".csv"; - File file; - for(NotifyBody nb : NotifyBody.getAll()) { - file = new File(logDir,String.format(fmt, nb.name())); - if(file.exists()) { - trans.info().printf("Processing '%s' in %s",nb.type(),file.getCanonicalPath()); - notifyFile.add(file); - } else { - trans.info().printf("No Files found for %s",nb.name()); - } - } - } } + /* + * Note: We try to put things related to Notify as Main Class in Run, where we might have put in + * Constructor, so that we can have other Classes call just the "notify" method. + */ @Override protected void run(AuthzTrans trans) { - List<String> toList = new ArrayList<>(); - List<String> ccList = new ArrayList<>(); AuthzTrans noAvg = trans.env().newTransNoAvg(); - String subject = "Test Notify"; - boolean urgent = false; - - - final Notify notify = this; final Holder<List<String>> info = new Holder<>(null); final Set<String> errorSet = new HashSet<>(); try { + // Class Load possible data + NotifyBody.load(env.access()); + + + // Create Intermediate Output + File logDir = logDir(); + Set<File> notifyFile = new HashSet<>(); + if(args().length>0) { + for(int i=0;i<args().length;++i) { + notifyFile.add(new File(logDir, args()[i])); + } + } else { + String fmt = "%s"+Chrono.dateOnlyStamp()+".csv"; + File file; + for(NotifyBody nb : NotifyBody.getAll()) { + file = new File(logDir,String.format(fmt, nb.name())); + if(file.exists()) { + trans.info().printf("Processing '%s' in %s",nb.type(),file.getCanonicalPath()); + notifyFile.add(file); + } else { + trans.info().printf("No Files found for %s",nb.name()); + } + } + } + for(File f : notifyFile) { CSV csv = new CSV(env.access(),f); try { @@ -167,8 +169,7 @@ } if(info.get()==null) { throw new CadiException("First line of Feed MUST contain 'info' record"); - } - String key = row.get(0)+'|'+info.get().get(1); + } String key = row.get(0)+'|'+info.get().get(1); NotifyBody body = NotifyBody.get(key); if(body==null) { errorSet.add("No NotifyBody defined for " + key); @@ -185,78 +186,93 @@ // now create Notification for(NotifyBody nb : NotifyBody.getAll()) { - String run = nb.type()+nb.name(); - String test = dryRun?run:null; - ONE_EMAIL: - for(String id : nb.users()) { + notify(noAvg, nb); + } - toList.clear(); - ccList.clear(); - try { - Identity identity = trans.org().getIdentity(noAvg, id); - if(identity==null) { - trans.warn().printf("%s is invalid for this Organization. Skipping notification.",id); - } else { - if(!identity.isPerson()) { - identity = identity.responsibleTo(); - } - if(identity==null) { - trans.warn().printf("Responsible Identity %s is invalid for this Organization. Skipping notification.",id); - } else { - for(int i=1;i<=nb.escalation();++i) { - if(identity != null) { - if(i==1) { - toList.add(identity.email()); - List<String> dels = identity.delegate(); - if(dels!=null) { - for(String d : dels) { - toList.add(d); - } - } - } else { - Identity s = identity.responsibleTo(); - if(s==null) { - trans.error().printf("Identity %s has no %s", identity.fullID(), - identity.isPerson()?"supervisor":"sponsor"); - } else { - ccList.add(s.email()); - } - } + } catch (APIException | IOException e1) { + trans.error().log(e1); + } finally { + for(String s : errorSet) { + trans.audit().log(s); + } + } + } + + public int notify(AuthzTrans trans, NotifyBody nb) { + List<String> toList = new ArrayList<>(); + List<String> ccList = new ArrayList<>(); + + String run = nb.type()+nb.name(); + String test = dryRun?run:null; + String last = null; + + ONE_EMAIL: + for(String id : nb.users()) { + last = id; + toList.clear(); + ccList.clear(); + try { + Identity identity = trans.org().getIdentity(trans, id); + if(identity==null) { + trans.warn().printf("%s is invalid for this Organization. Skipping notification.",id); + } else { + if(!identity.isPerson()) { + identity = identity.responsibleTo(); + } + if(identity==null) { + trans.warn().printf("Responsible Identity %s is invalid for this Organization. Skipping notification.",id); + } else { + for(int i=1;i<=nb.escalation();++i) { + if(identity != null) { + if(i==1) { // self and Delegates + toList.add(identity.email()); + List<String> dels = identity.delegate(); + if(dels!=null) { + for(String d : dels) { + toList.add(d); } } - - StringBuilder content = new StringBuilder(); - content.append(String.format(header,version,Identity.mixedCase(identity.firstName()))); - - nb.body(noAvg, content, indent, notify, id); - content.append(footer); - - if(mailer.sendEmail(noAvg, test, toList, ccList, nb.subject(),content.toString(), urgent)) { - nb.inc(); + } else { + Identity s = identity.responsibleTo(); + if(s==null) { + trans.error().printf("Identity %s has no %s", identity.fullID(), + identity.isPerson()?"supervisor":"sponsor"); } else { - trans.error().log("Mailer failed to send Mail"); - } - if(maxEmails>0 && nb.count()>=maxEmails) { - break ONE_EMAIL; + ccList.add(s.email()); } } } - } catch (OrganizationException e) { - trans.error().log(e); } - } - trans.info().printf("Emailed %d for %s",nb.count(),run); - } + StringBuilder content = new StringBuilder(); + content.append(String.format(header,version,Identity.mixedCase(identity.firstName()))); - } finally { - for(String s : errorSet) { - trans.audit().log(s); + nb.body(trans, content, indent, this, id); + content.append(footer); + + if(mailer.sendEmail(trans, test, toList, ccList, nb.subject(),content.toString(), urgent)) { + nb.inc(); + } else { + trans.error().log("Mailer failed to send Mail"); + } + if(maxEmails>0 && nb.count()>=maxEmails) { + break ONE_EMAIL; + } + } + } + } catch (OrganizationException e) { + trans.error().log(e); } } + if(nb.count()<=1) { + trans.info().printf("Notified %s for %s",last,run); + } else { + trans.info().printf("Emailed %d for %s",nb.count(),run); + } + return nb.count(); } - @Override + @Override protected void _close(AuthzTrans trans) { } 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 034286cf..bf20eb41 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 @@ -195,16 +195,24 @@ public abstract class NotifyBody { } } - protected void println(StringBuilder sb, int indent, Object ... objs) { + protected void print(StringBuilder sb, int indent, Object ... objs) { for(int i=0;i<indent;++i) { sb.append(' '); } for(Object o : objs) { sb.append(o.toString()); } + } + + protected void println(StringBuilder sb, int indent, Object ... objs) { + print(sb,indent,objs); sb.append('\n'); } - + + protected void printf(StringBuilder sb, int indent, String fmt, Object ... objs) { + print(sb,indent,String.format(fmt, objs)); + } + protected String printCell(StringBuilder sb, int indent, String current, String prev) { if(current.equals(prev)) { println(sb,indent,DUPL); 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 deac3e41..94502d9f 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 @@ -36,7 +36,8 @@ public abstract class NotifyCredBody extends NotifyBody { super(access,"cred",name); // Default - explanation = "The following Credentials are expiring on the dates shown. " + explanation = "The following Credentials that you are responsible for " + + "are expiring on the dates shown. " + "Failure to act before the expiration date will cause your App's " + "Authentications to fail." + "<h3>Instructions for 'Password':</h3><ul>" diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyPendingApprBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyPendingApprBody.java index 502464e9..df28503c 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyPendingApprBody.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/NotifyPendingApprBody.java @@ -27,64 +27,27 @@ import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.cadi.Access; public class NotifyPendingApprBody extends NotifyBody { - private final String explanation; public NotifyPendingApprBody(Access access) { super(access,"appr","PendingApproval"); - explanation = "The following Approvals are awaiting your action. "; } @Override public boolean body(AuthzTrans trans, StringBuilder sb, int indent, Notify n, String id) { - println(sb,indent,explanation); -/* println(sb,indent,"<table>"); - indent+=2; - println(sb,indent,"<tr>"); - indent+=2; - println(sb,indent,"<th>Fully Qualified ID</th>"); - println(sb,indent,"<th>Unique ID</th>"); - println(sb,indent,"<th>Type</th>"); - println(sb,indent,"<th>Expires</th>"); - println(sb,indent,"<th>Warnings</th>"); - indent-=2; - println(sb,indent,"</tr>"); - String theid, type, info, expires, warnings; - GregorianCalendar gc = new GregorianCalendar(); + boolean rv = false; for(List<String> row : rows.get(id)) { - theid=row.get(1); - switch(row.get(3)) { - case "1": - case "2": - type = "Password"; - break; - case "200": - type = "x509 (Certificate)"; - break; - default: - type = "Unknown, see AAF GUI"; - break; + String qty = row.get(2); + if("1".equals(qty)) { + printf(sb,indent,"You have an Approval in the AAF %s Environment awaiting your decision.\n",row.get(3)); + } else { + printf(sb,indent,"You have %s Approvals in the AAF %s Environment awaiting your decision.\n",qty,row.get(3)); } - theid = "<a href=\""+n.guiURL+"/creddetail?ns="+row.get(2)+"\">"+theid+"</a>"; - gc.setTimeInMillis(Long.parseLong(row.get(5))); - expires = Chrono.niceUTCStamp(gc); - info = row.get(6); - //TODO get Warnings - warnings = ""; - - println(sb,indent,"<tr>"); - indent+=2; - printCell(sb,indent,theid); - printCell(sb,indent,info); - printCell(sb,indent,type); - printCell(sb,indent,expires); - printCell(sb,indent,warnings); - indent-=2; - println(sb,indent,"</tr>"); + printf(sb,indent,"<br><br><b>ACTION:</b> <i>Click on</i> <a href=\"%s/approve\">AAF Approval Page</a>",n.guiURL); + rv = true; + break; // only one } - indent-=2; - println(sb,indent,"</table>"); - */ - return true; + + return rv; } @Override @@ -100,4 +63,14 @@ public class NotifyPendingApprBody extends NotifyBody { return String.format("AAF Pending Approval Notification (ENV: %s)",env); } + /* (non-Javadoc) + * @see org.onap.aaf.auth.batch.reports.bodies.NotifyBody#store(java.util.List) + */ + @Override + public void store(List<String> row) { + // Notify Pending is setup for 1 Notification at a time + super.rows.clear(); + super.store(row); + } + } diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/TwoMonthNotifyCredBody.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/TwoMonthNotifyCredBody.java new file mode 100644 index 00000000..eb52c6d0 --- /dev/null +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/bodies/TwoMonthNotifyCredBody.java @@ -0,0 +1,37 @@ +/** + * ============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.batch.reports.bodies; + +import java.io.IOException; + +import org.onap.aaf.auth.batch.helpers.ExpireRange; +import org.onap.aaf.cadi.Access; + +public class TwoMonthNotifyCredBody extends NotifyCredBody { + public TwoMonthNotifyCredBody(Access access) throws IOException { + super(access, ExpireRange.TWO_MONTH); + } + + @Override + public String subject() { + return String.format("AAF Two Month Credential Notification (ENV: %s)",env); + } +} diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/temp/DataMigrateDublin.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/temp/DataMigrateDublin.java new file mode 100644 index 00000000..4851662b --- /dev/null +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/temp/DataMigrateDublin.java @@ -0,0 +1,215 @@ +/** + * ============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.batch.temp; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +import org.onap.aaf.auth.batch.Batch; +import org.onap.aaf.auth.batch.BatchPrincipal; +import org.onap.aaf.auth.batch.helpers.CQLBatch; +import org.onap.aaf.auth.batch.helpers.CQLBatchLoop; +import org.onap.aaf.auth.dao.cass.CredDAO; +import org.onap.aaf.auth.env.AuthzTrans; +import org.onap.aaf.auth.org.OrganizationException; +import org.onap.aaf.cadi.Hash; +import org.onap.aaf.cadi.configure.Factory; +import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.Env; +import org.onap.aaf.misc.env.TimeTaken; + +import com.datastax.driver.core.ResultSet; +import com.datastax.driver.core.Row; + +public class DataMigrateDublin extends Batch { + private final SecureRandom sr; + private final AuthzTrans noAvg; + + public DataMigrateDublin(AuthzTrans trans) throws APIException, IOException, OrganizationException { + super(trans.env()); + trans.info().log("Starting Connection Process"); + + noAvg = env.newTransNoAvg(); + noAvg.setUser(new BatchPrincipal("Migrate")); + + TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB); + try { + TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE); + try { + session = cluster.connect(); + } finally { + tt.done(); + } + } finally { + tt0.done(); + } + + sr = new SecureRandom(); + } + + @Override + protected void run(AuthzTrans trans) { + /////////////////////////// + trans.info().log("Add UniqueTag to Passwords"); + + CQLBatchLoop cbl = new CQLBatchLoop(new CQLBatch(noAvg.info(),session), 50, dryRun); + try { + ResultSet rs = session.execute("SELECT id,type,expires,cred,tag FROM authz.cred"); + Iterator<Row> iter = rs.iterator(); + Row row; + int count = 0; + byte[] babytes = new byte[6]; + Map<String, List<CredInfo>> mlci = new TreeMap<>(); + Map<String, String> ba_tag = new TreeMap<>(); + while(iter.hasNext()) { + ++count; + row = iter.next(); + String tag = row.getString(4); + int type = row.getInt(1); + switch(type) { + case CredDAO.BASIC_AUTH: + case CredDAO.BASIC_AUTH_SHA256: + String key = row.getString(0) + '|' + type + '|' + Hash.toHex(row.getBytesUnsafe(3).array()); + String btag = ba_tag.get(key); + if(btag == null) { + if(tag==null || tag.isEmpty()) { + sr.nextBytes(babytes); + btag = Hash.toHexNo0x(babytes); + } else { + btag = tag; + } + ba_tag.put(key, btag); + } + + if(!btag.equals(tag)) { + cbl.preLoop(); + update(cbl,row,btag); + } + break; + case CredDAO.CERT_SHA256_RSA: + if(tag==null || tag.isEmpty()) { + String id = row.getString(0); + List<CredInfo> ld = mlci.get(id); + if(ld==null) { + ld = new ArrayList<>(); + mlci.put(id,ld); + } + ld.add(new CredInfo(id,row.getInt(1),row.getTimestamp(2))); + } + break; + } + } + cbl.flush(); + trans.info().printf("Processes %d cred records, updated %d records in %d batches.", count, cbl.total(), cbl.batches()); + count = 0; + + cbl.reset(); + + trans.info().log("Add Serial to X509 Creds"); + rs = session.execute("SELECT ca, id, x509 FROM authz.x509"); + iter = rs.iterator(); + while(iter.hasNext()) { + ++count; + row = iter.next(); + String ca = row.getString(0); + String id = row.getString(1); + List<CredInfo> list = mlci.get(id); + if(list!=null) { + ByteBuffer bb = row.getBytesUnsafe(2); + if(bb!=null) { + Collection<? extends Certificate> x509s = Factory.toX509Certificate(bb.array()); + for(Certificate c : x509s) { + X509Certificate xc = (X509Certificate)c; + for(CredInfo ci : list) { + if(xc.getNotAfter().equals(ci.expires)) { + cbl.preLoop(); + ci.update(cbl, ca + '|' + xc.getSerialNumber()); + break; + } + } + } + } + } + } + cbl.flush(); + trans.info().printf("Processed %d x509 records, updated %d records in %d batches.", count, cbl.total(), cbl.batches()); + count = 0; + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static class CredInfo { + public final String id; + public final int type; + public final Date expires; + + public CredInfo(String id, int type, Date expires) { + this.id = id; + this.type = type; + this.expires = expires; + } + + public void update(CQLBatchLoop cbl, String newtag) { + StringBuilder sb = cbl.inc(); + sb.append("UPDATE authz.cred SET tag='"); + sb.append(newtag); + sb.append("' WHERE id='"); + sb.append(id); + sb.append("' AND type="); + sb.append(type); + sb.append(" AND expires=dateof(maxtimeuuid("); + sb.append(expires.getTime()); + sb.append("));"); + } + } + + private void update(CQLBatchLoop cbl, Row row, String newtag) { + StringBuilder sb = cbl.inc(); + sb.append("UPDATE authz.cred SET tag='"); + sb.append(newtag); + sb.append("' WHERE id='"); + sb.append(row.getString(0)); + sb.append("' AND type="); + sb.append(row.getInt(1)); + sb.append(" AND expires=dateof(maxtimeuuid("); + Date lc = row.getTimestamp(2); + sb.append(lc.getTime()); + sb.append("));"); + } + + @Override + protected void _close(AuthzTrans trans) { + trans.info().log("End " + this.getClass().getSimpleName() + " processing" ); + session.close(); + } + +} diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Approvals.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Approvals.java index 2047098a..03c812ae 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Approvals.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Approvals.java @@ -38,15 +38,21 @@ import org.onap.aaf.auth.batch.approvalsets.ApprovalSet; import org.onap.aaf.auth.batch.approvalsets.Pending; import org.onap.aaf.auth.batch.approvalsets.URApprovalSet; import org.onap.aaf.auth.batch.helpers.BatchDataView; +import org.onap.aaf.auth.batch.helpers.CQLBatch; +import org.onap.aaf.auth.batch.helpers.CQLBatchLoop; +import org.onap.aaf.auth.batch.helpers.LastNotified; import org.onap.aaf.auth.batch.helpers.NS; import org.onap.aaf.auth.batch.helpers.Notification; +import org.onap.aaf.auth.batch.helpers.Notification.TYPE; import org.onap.aaf.auth.batch.helpers.Role; import org.onap.aaf.auth.batch.helpers.UserRole; +import org.onap.aaf.auth.batch.reports.Notify; import org.onap.aaf.auth.batch.reports.bodies.NotifyPendingApprBody; import org.onap.aaf.auth.dao.cass.UserRoleDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; import org.onap.aaf.auth.org.OrganizationException; +import org.onap.aaf.cadi.Access; import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.client.Holder; import org.onap.aaf.cadi.util.CSV; @@ -56,15 +62,18 @@ import org.onap.aaf.misc.env.Trans; import org.onap.aaf.misc.env.util.Chrono; public class Approvals extends Batch { - private final AuthzTrans noAvg; + private final Access access; + private final AuthzTrans noAvg; private BatchDataView dataview; private List<CSV> csvList; private GregorianCalendar now; + private final Notify notify; public Approvals(AuthzTrans trans) throws APIException, IOException, OrganizationException { super(trans.env()); - + notify = new Notify(trans); + access = env.access(); noAvg = env.newTransNoAvg(); noAvg.setUser(new BatchPrincipal("batch:Approvals")); session = cluster.connect(); @@ -94,13 +103,13 @@ public class Approvals extends Batch { trans.error().printf("CSV File %s does not exist",f.getAbsolutePath()); } } - } @Override protected void run(AuthzTrans trans) { Map<String,Pending> mpending = new TreeMap<>(); Holder<Integer> count = new Holder<>(0); + final CQLBatchLoop cbl = new CQLBatchLoop(new CQLBatch(noAvg.info(),session),100,dryRun); for(CSV approveCSV : csvList) { TimeTaken tt = trans.start("Load Analyzed Reminders",Trans.SUB,approveCSV.name()); try { @@ -170,19 +179,36 @@ public class Approvals extends Batch { trans.info().printf("Processed %d UserRoles", count.get()); count.set(0); - NotifyPendingApprBody npab; + NotifyPendingApprBody npab = new NotifyPendingApprBody(access); + GregorianCalendar gc = new GregorianCalendar(); gc.add(GregorianCalendar.DAY_OF_MONTH, 7); Date oneWeek = gc.getTime(); + CSV.Saver rs = new CSV.Saver(); + + tt = trans.start("Obtain Last Notifications", Trans.SUB); + LastNotified lastN; + try { + lastN = new LastNotified(session); + lastN.add(mpending.keySet()); + } finally { + tt.done(); + } Pending p; tt = trans.start("Notify for Pending", Trans.SUB); try { for(Entry<String, Pending> es : mpending.entrySet()) { p = es.getValue(); - Date earliest = p.earliest(); - if(p.newApprovals() || earliest==null || earliest.before(oneWeek) ) { - System.out.println("update"); + Date dateLastNotified = lastN.lastNotified(es.getKey()); + if(p.newApprovals() || dateLastNotified==null || dateLastNotified.after(oneWeek) ) { + rs.row("appr", es.getKey(),p.qty(),batchEnv); + npab.store(rs.asList()); + if(notify.notify(noAvg, npab)>0) { + // Update + cbl.preLoop(); + update(cbl.inc(),es.getKey(),Notification.TYPE.OA); + } } } } finally { @@ -192,7 +218,16 @@ public class Approvals extends Batch { } } - @Override + private void update(StringBuilder sb, String user, TYPE oa) { + sb.append("UPDATE authz.notify SET last=dateof(now()) WHERE user='"); + sb.append(user); + sb.append("' AND type="); + sb.append(oa.idx()); + sb.append(';'); + + } + + @Override protected void _close(AuthzTrans trans) { if(session!=null) { session.close(); diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java index a0fdcc50..7a30dc5f 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java @@ -138,6 +138,8 @@ public class Remove extends Batch { if(!ur.get()) { ur.set(true); } + //TODO If deleted because Role is no longer there, double check... + UserRole.batchDelete(cbl.inc(),row); hdd.target=UserRoleDAO.TABLE; hdd.subject=UserRole.histSubject(row); diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/actions/test/JU_URFutureApproveExec.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/actions/test/JU_URFutureApproveExec.java index 35409042..58d52f7d 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/actions/test/JU_URFutureApproveExec.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/actions/test/JU_URFutureApproveExec.java @@ -131,7 +131,7 @@ public class JU_URFutureApproveExec { // TODO Auto-generated catch block e.printStackTrace(); } - Approval approval = new Approval(null, null, "", new Date(), "test", "", "", "", "", 0L); + Approval approval = new Approval(null, null, "", "test", "", "", "", "", 0L); List<Approval> approvalAL = new ArrayList<>(); Future futureObj = new Future(null, "", "", new Date(), new Date(), null); @@ -151,7 +151,7 @@ public class JU_URFutureApproveExec { // TODO Auto-generated catch block e.printStackTrace(); } - Approval approval = new Approval(null, null, "", new Date(), "test", "", "", "", "", 0L); + Approval approval = new Approval(null, null, "", "test", "", "", "", "", 0L); List<Approval> approvalAL = new ArrayList<>(); Future futureObj = new Future(null, "", "", new Date(), new Date(), null); @@ -171,7 +171,7 @@ public class JU_URFutureApproveExec { // TODO Auto-generated catch block e.printStackTrace(); } - Approval approval = new Approval(null, null, "", new Date(), "test", "", "", "", "", 0L); + Approval approval = new Approval(null, null, "", "test", "", "", "", "", 0L); List<Approval> approvalAL = new ArrayList<>(); Future futureObj = new Future(null, "", "", new Date(), new Date(), null); @@ -191,7 +191,7 @@ public class JU_URFutureApproveExec { // TODO Auto-generated catch block e.printStackTrace(); } - Approval approval = new Approval(null, null, "", new Date(), "test", "", "", "", "", 0L); + Approval approval = new Approval(null, null, "", "test", "", "", "", "", 0L); List<Approval> approvalAL = new ArrayList<>(); Future futureObj = new Future(null, "", "", new Date(), new Date(), null); @@ -211,7 +211,7 @@ public class JU_URFutureApproveExec { // TODO Auto-generated catch block e.printStackTrace(); } - Approval approval = new Approval(null, null, "", new Date(), "test", "", "", "", "", 0L); + Approval approval = new Approval(null, null, "", "test", "", "", "", "", 0L); List<Approval> approvalAL = new ArrayList<>(); Future futureObj = new Future(null, "", "", new Date(), new Date(), null); diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Approval.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Approval.java index 44c72763..2e51d076 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Approval.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Approval.java @@ -27,14 +27,12 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.UUID; import org.junit.Before; import org.junit.Test; import org.onap.aaf.auth.batch.helpers.Approval; -import org.onap.aaf.auth.batch.helpers.creators.RowCreator; import org.onap.aaf.auth.dao.cass.ApprovalDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; @@ -47,15 +45,14 @@ public class JU_Approval { Approval approval; UUID id; UUID ticket; - Date date; + @Before public void setUp() { id = new UUID(0, 0); ticket = new UUID(0, 0); - date = new Date(); - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver","user", "memo", "operation", "status", "type", 100l); } @Test @@ -72,15 +69,15 @@ public class JU_Approval { approval.expunge(); } - @Test - public void testGetLast_notified() { - Assert.assertTrue(approval.getLast_notified() instanceof Date); - } - - @Test - public void testSetLastNotified() { - approval.setLastNotified(date); - } +// @Test +// public void testGetLast_notified() { +// Assert.assertTrue(approval.getLast_notified() instanceof Date); +// } +// +// @Test +// public void testSetLastNotified() { +// approval.setLastNotified(date); +// } @Test public void testGetStatus() { @@ -144,31 +141,31 @@ public class JU_Approval { @Test public void testUpdateNonDryRun() { - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver", "user", "memo", "operation", "status", "type", 100l); AuthzTrans trans = mock(AuthzTrans.class); ApprovalDAO dao = mock(ApprovalDAO.class); LogTarget target = mock(LogTarget.class); when(trans.info()).thenReturn(target); - approval.update(trans, dao, false); +// approval.update(trans, dao, false); } @Test public void testUpdateDryRun() { - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver", "user", "memo", "operation", "status", "type", 100l); AuthzTrans trans = mock(AuthzTrans.class); ApprovalDAO dao = mock(ApprovalDAO.class); LogTarget target = mock(LogTarget.class); when(trans.info()).thenReturn(target); - approval.update(trans, dao, true); +// approval.update(trans, dao, true); } @Test public void testDelayDeleteDryRun() { - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver", "user", "memo", "operation", "status", "type", 100l); AuthzTrans trans = mock(AuthzTrans.class); ApprovalDAO dao = mock(ApprovalDAO.class); LogTarget target = mock(LogTarget.class); @@ -182,7 +179,7 @@ public class JU_Approval { @Test public void testDelayDeleteNonDryRun() { - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver", "user", "memo", "operation", "status", "type", 100l); AuthzTrans trans = mock(AuthzTrans.class); ApprovalDAO dao = mock(ApprovalDAO.class); LogTarget target = mock(LogTarget.class); @@ -198,7 +195,7 @@ public class JU_Approval { @Test public void testDelayDeleteResultNotOk() { - approval = new Approval(id, ticket, "approver", date, "user", "memo", "operation", "status", "type", 100l); + approval = new Approval(id, ticket, "approver", "user", "memo", "operation", "status", "type", 100l); AuthzTrans trans = mock(AuthzTrans.class); ApprovalDAO dao = mock(ApprovalDAO.class); LogTarget target = mock(LogTarget.class); @@ -212,14 +209,5 @@ public class JU_Approval { Approval.delayDelete(trans, dao, false, list, "text"); } - @Test - public void testv2() { - Approval.v2_0_17.create(RowCreator.getRow()); - - assertEquals( - "select id,ticket,approver,last_notified,user,memo,operation,status,type,WRITETIME(status) from authz.approval", - Approval.v2_0_17.select()); - - } } diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Future.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Future.java index 0db682ad..e551ce2b 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Future.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_Future.java @@ -36,7 +36,6 @@ import org.junit.Before; import org.junit.Test; import org.onap.aaf.auth.batch.helpers.Creator; import org.onap.aaf.auth.batch.helpers.Future; -import org.onap.aaf.auth.batch.helpers.creators.RowCreator; import org.onap.aaf.auth.dao.cass.FutureDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; @@ -109,40 +108,6 @@ public class JU_Future { Assert.assertEquals(false, Future.pendingDelete(future)); } - @Test - public void testLoad() { - Session session = mock(Session.class); - Trans trans = mock(Trans.class); - @SuppressWarnings("unchecked") - Creator<Future> creator = (Creator<Future>)mock(Creator.class); - LogTarget target = mock(LogTarget.class); - TimeTaken tt = mock(TimeTaken.class); - ResultSet results = mock(ResultSet.class); - ArrayList<Row> rows = new ArrayList<Row>(); - Row row = RowCreator.getRow(); - rows.add(row); - - when(results.all()).thenReturn(rows); - when(trans.info()).thenReturn(target); - when(trans.start("Load Futures", Env.REMOTE)).thenReturn(tt); - when(trans.start("Process Futures", Env.SUB)).thenReturn(tt); - when(session.execute(any(SimpleStatement.class))).thenReturn(results); - when(creator.create(row)).thenReturn(future); - - Future.load(trans, session, creator); - } - - @Test - public void testV2() { - Future.v2_0_17.create(RowCreator.getRow()); - assertEquals(Future.v2_0_17.select(), "select id,memo,target,start,expires from authz.future"); - } - - @Test - public void testWithConstruct() { - Future.withConstruct.create(RowCreator.getRow()); - assertEquals(Future.withConstruct.select(), "select id,memo,target,start,expires,construct from authz.future"); - } @Test public void testDelayedDeleteWithDryRun() { diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_UserRole.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_UserRole.java index 6b7011c6..5b20ce22 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_UserRole.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/helpers/test/JU_UserRole.java @@ -36,7 +36,6 @@ import org.junit.Test; import org.onap.aaf.auth.batch.actions.URDelete; import org.onap.aaf.auth.batch.helpers.Creator; import org.onap.aaf.auth.batch.helpers.UserRole; -import org.onap.aaf.auth.batch.helpers.creators.RowCreator; import org.onap.aaf.auth.dao.cass.UserRoleDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.misc.env.Env; @@ -153,11 +152,6 @@ public class JU_UserRole { userRole.actuateDeletionNow(trans, urd); } - @Test - public void testV2() { - UserRole.v2_0_11.create(RowCreator.getRow()); - assertEquals("select user,role,ns,rname,expires from authz.user_role", UserRole.v2_0_11.select()); - } @Test public void testLoad() { @@ -176,11 +170,6 @@ public class JU_UserRole { when(session.execute(any(SimpleStatement.class))).thenReturn(results); when(results.iterator()).thenReturn(rows.iterator()); - List<Row> list = new ArrayList<Row>(); - list.add(RowCreator.getRow()); - list.add(RowCreator.getRow()); - - UserRole.load(trans, session, creator, new UserRole.DataLoadVisitor()); } } diff --git a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/test/JU_NotificationTest.java b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/test/JU_NotificationTest.java index 79e4168e..f1cba0b7 100644 --- a/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/test/JU_NotificationTest.java +++ b/auth/auth-batch/src/test/java/org/onap/aaf/auth/batch/test/JU_NotificationTest.java @@ -33,7 +33,6 @@ import org.onap.aaf.auth.batch.actions.Message; import org.onap.aaf.auth.batch.helpers.Creator; import org.onap.aaf.auth.batch.helpers.Notification; import org.onap.aaf.auth.batch.helpers.Notification.TYPE; -import org.onap.aaf.auth.batch.helpers.creators.RowCreator; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.LogTarget; @@ -73,8 +72,6 @@ public class JU_NotificationTest { assertTrue(notification.update(trans, null, true)); assertTrue(notification.toString().contains("\"user\",\"CN\",")); - Notification.v2_0_18.create(RowCreator.getRow()); - assertEquals(Notification.v2_0_18.select(), "SELECT user,type,last,checksum FROM authz.notify LIMIT 100000"); } }
\ No newline at end of file diff --git a/auth/auth-cass/cass_init/init.cql b/auth/auth-cass/cass_init/init.cql index 04540799..75b02c53 100644 --- a/auth/auth-cass/cass_init/init.cql +++ b/auth/auth-cass/cass_init/init.cql @@ -168,6 +168,8 @@ CREATE TABLE future ( memo varchar, // Description start timestamp, // When it should take effect expires timestamp, // When not longer valid + target_key varchar, // Item Key (or 2nd key, assuming user is first) + target_date timestamp, // Item's relevant date/stamp construct blob, // How to construct this object (like History) PRIMARY KEY(id) ); diff --git a/auth/auth-cass/cass_init/init2_10.cql b/auth/auth-cass/cass_init/init2_10.cql index 839acf60..b7195076 100644 --- a/auth/auth-cass/cass_init/init2_10.cql +++ b/auth/auth-cass/cass_init/init2_10.cql @@ -1,2 +1,4 @@ use authz; alter TABLE cred ADD tag varchar; +alter TABLE future ADD target_key varchar; +alter TABLE future ADD target_date timestamp; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/ApprovalDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/ApprovalDAO.java index cc4135ee..4c66c964 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/ApprovalDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/ApprovalDAO.java @@ -76,7 +76,7 @@ public class ApprovalDAO extends CassDAOImpl<AuthzTrans,ApprovalDAO.Data> { public String status; public String memo; public String operation; - public Date last_notified; +// public Date last_notified; public Date updated; } @@ -97,11 +97,11 @@ public class ApprovalDAO extends CassDAOImpl<AuthzTrans,ApprovalDAO.Data> { data.status = row.getString(5); data.memo = row.getString(6); data.operation = row.getString(7); - data.last_notified = row.getTimestamp(8); +// data.last_notified = row.getTimestamp(8); // This is used to get "WRITETIME(STATUS)" from Approval, which gives us an "updated" - if (row.getColumnDefinitions().size()>9) { + if (row.getColumnDefinitions().size()>8) { // Rows reported in MicroSeconds - data.updated = new Date(row.getLong(9)/1000); + data.updated = new Date(row.getLong(8)/1000); } return data; } @@ -121,12 +121,12 @@ public class ApprovalDAO extends CassDAOImpl<AuthzTrans,ApprovalDAO.Data> { obj[++idx]=data.status; obj[++idx]=data.memo; obj[++idx]=data.operation; - obj[++idx]=data.last_notified; +// obj[++idx]=data.last_notified; } } private void init(AuthzTrans trans) { - String[] helpers = setCRUD(trans, TABLE, Data.class, ApprovalLoader.deflt,9); + String[] helpers = setCRUD(trans, TABLE, Data.class, ApprovalLoader.deflt,8); psByUser = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + ", WRITETIME(status) FROM " + TABLE + " WHERE user = ?", new ApprovalLoader(1) { @Override diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java index 9a47e576..01cc9237 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java @@ -84,6 +84,7 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { public Integer other; public String ns; public String tag; + public String notes; public ByteBuffer cred; // this is a blob in cassandra @@ -129,7 +130,8 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { data.other = row.getInt(3); data.ns = row.getString(4); data.tag = row.getString(5); - data.cred = row.getBytesUnsafe(6); + data.notes = row.getString(6); + data.cred = row.getBytesUnsafe(7); return data; } @@ -148,6 +150,7 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { obj[i=idx] = data.other; obj[++i] = data.ns; obj[++i] = data.tag; + obj[++i] = data.notes; obj[++i] = data.cred; } @@ -160,6 +163,7 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { os.writeInt(data.other==null?0:data.other); writeString(os, data.ns); writeString(os, data.tag); + writeString(os, data.notes); if (data.cred==null) { os.writeInt(-1); } else { @@ -182,6 +186,7 @@ public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> { data.other = is.readInt(); data.ns = readString(is,buff); data.tag = readString(is,buff); + data.notes = readString(is,buff); int i = is.readInt(); data.cred=null; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java index 10c0ec97..7831815f 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java @@ -65,11 +65,13 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { public static class Data { public UUID id; - public String target; - public String memo; - public Date start; - public Date expires; - public ByteBuffer construct; // this is a blob in cassandra + public String target; + public String memo; + public Date start; + public Date expires; + public String target_key; + public Date target_date; + public ByteBuffer construct; // this is a blob in cassandra } private static class FLoader extends Loader<Data> { @@ -83,12 +85,14 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { @Override public Data load(Data data, Row row) { - data.id = row.getUUID(0); - data.target = row.getString(1); - data.memo = row.getString(2); - data.start = row.getTimestamp(3); - data.expires = row.getTimestamp(4); - data.construct = row.getBytes(5); + data.id = row.getUUID(0); + data.target = row.getString(1); + data.memo = row.getString(2); + data.start = row.getTimestamp(3); + data.expires = row.getTimestamp(4); + data.construct = row.getBytes(5); + data.target_key = row.getString(6); + data.target_date = row.getTimestamp(7); return data; } @@ -106,6 +110,8 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> { obj[++idx] = data.start; obj[++idx] = data.expires; obj[++idx] = data.construct; + obj[++idx] = data.target_key; + obj[++idx] = data.target_date; } } diff --git a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/JU_AAF_CM.java b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/JU_AAF_CM.java index ab3172f0..1bee730a 100644 --- a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/JU_AAF_CM.java +++ b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/JU_AAF_CM.java @@ -164,7 +164,7 @@ public class JU_AAF_CM { } catch (CadiException | LocatorException e) { // TODO Auto-generated catch block e.printStackTrace(); - assertTrue(e.getMessage().contains("NoSuchAlgorithmException")); + assertTrue(e.getMessage().contains("Error initializing Context: TLS")); } // assertTrue(obj instanceof CA); } diff --git a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/facade/JU_FacadeImpl.java b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/facade/JU_FacadeImpl.java index 1da45477..a9806439 100644 --- a/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/facade/JU_FacadeImpl.java +++ b/auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/facade/JU_FacadeImpl.java @@ -83,7 +83,7 @@ public class JU_FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> { @Override public void log(Throwable e, Object... msgs) { e.getMessage(); - e.printStackTrace(); + //e.printStackTrace(); msgs.toString(); } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java index 5f7fa410..2bae29b5 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java @@ -33,7 +33,7 @@ import org.onap.aaf.misc.env.LogTarget; import org.onap.aaf.misc.env.TransStore; public interface AuthzTrans extends TransStore { - public enum REQD_TYPE {future(1),force(2),move(4),ns(8); + public enum REQD_TYPE {future(1),force(2),move(4),ns(8),detail(16); public final int bit; REQD_TYPE(int bit) { 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 index 1db11985..2e3801ed 100644 --- 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 @@ -58,7 +58,8 @@ public class FileMailer implements Mailer { } boolean dryrun = Boolean.parseBoolean(access.getProperty("DRY_RUN","false")); - int maxEmail = Integer.parseInt(access.getProperty("MAX_EMAIL", "-1")); + String str = access.getProperty("MAX_EMAIL", null); + int maxEmail = str==null || str.isEmpty()?Integer.MAX_VALUE:Integer.parseInt(str); if(dryrun && maxEmail==1) { testName = "email_test"; } else { diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java index 2d0a82a8..1256c601 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java @@ -45,11 +45,10 @@ import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.onap.aaf.auth.org.OrganizationException; import org.onap.aaf.auth.rserv.RServlet; +import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.LocatorException; -import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.config.Config; -import org.onap.aaf.cadi.config.SecurityInfo; import org.onap.aaf.misc.env.Trans; import org.onap.aaf.misc.env.util.Split; import org.onap.aaf.misc.rosetta.env.RosettaEnv; @@ -81,7 +80,7 @@ public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> ex // Critical - if no Security Protocols set, then set it. We'll just get messed up if not if ((httpproto=props.get(Config.CADI_PROTOCOLS))==null) { if ((httpproto=props.get(Config.HTTPS_PROTOCOLS))==null) { - props.put(Config.CADI_PROTOCOLS, (httpproto=SecurityInfo.HTTPS_PROTOCOLS_DEFAULT)); + props.put(Config.CADI_PROTOCOLS, (httpproto=Config.HTTPS_PROTOCOLS_DEFAULT)); } else { props.put(Config.CADI_PROTOCOLS, httpproto); } @@ -133,7 +132,7 @@ public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> ex sslContextFactory.setTrustStorePassword(access().decrypt(truststorePassword, false)); } // Be able to accept only certain protocols, i.e. TLSv1.1+ - String subprotocols = access().getProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT); + String subprotocols = access().getProperty(Config.CADI_PROTOCOLS, Config.HTTPS_PROTOCOLS_DEFAULT); service.setSubprotocol(subprotocols); final String[] protocols = Split.splitTrim(',', subprotocols); sslContextFactory.setIncludeProtocols(protocols); @@ -215,7 +214,12 @@ public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> ex } } try { - register(service.registrants(port)); + String no_register = env().getProperty("aaf_no_register",null); + if(no_register==null) { + register(service.registrants(port)); + } else { + access().printf(Level.INIT,"'aaf_no_register' is set. %s will not be registered with Locator", service.app_name); + } access().printf(Level.INIT, "Starting Jetty Service for %s, version %s, on %s://%s:%d", service.app_name,service.app_version,protocol,hostname,port); //server.join(); } catch (Exception e) { diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/ApprovalForm.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/ApprovalForm.java index 27fd5274..f1730380 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/ApprovalForm.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/ApprovalForm.java @@ -67,7 +67,7 @@ public class ApprovalForm extends Page { // Package on purpose static final String NAME="Approvals"; static final String HREF = "/gui/approve"; - static final String[] FIELDS = new String[] {"line[]","user"}; + static final String[] FIELDS = new String[] {"line[]","user","delegate_of"}; public ApprovalForm(final AAF_GUI gui, final Page ... breadcrumbs) throws APIException, IOException { @@ -106,7 +106,6 @@ public class ApprovalForm extends Page { hgen.end(jsStart); } }); - } /** @@ -118,13 +117,15 @@ public class ApprovalForm extends Page { private static class Model extends TableData<AAF_GUI,AuthzTrans> { //TODO come up with a generic way to do ILM Info (people page) private static final String TODO_ILM_INFO = "TODO: ILM Info"; - private static final String DOMAIN_OF_USER = "@DOMAIN"; + private static final String[] headers = new String[] {"Identity","Request","Approve","Deny"}; private Slot sUser; + private Slot sAsDelegate; public Model(AuthzEnv env) { sUser = env.slot(NAME+".user"); + sAsDelegate = env.slot(NAME+".delegate_of"); } @Override @@ -135,6 +136,7 @@ public class ApprovalForm extends Page { @Override public Cells get(final AuthzTrans trans, final AAF_GUI gui) { final String userParam = trans.get(sUser, null); + final String asDelegate = trans.get(sAsDelegate, trans.user()); ArrayList<AbsCell[]> rv = new ArrayList<>(); String msg = null; TimeTaken tt = trans.start("AAF Get Approvals for Approver",Env.REMOTE); @@ -144,7 +146,7 @@ public class ApprovalForm extends Page { int numLeft = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Integer>() { @Override public Integer code(Rcli<?> client) throws CadiException, ConnectException, APIException { - Future<Approvals> fa = client.read("/authz/approval/approver/"+trans.user(),gui.getDF(Approvals.class)); + Future<Approvals> fa = client.read("/authz/approval/approver/"+asDelegate,gui.getDF(Approvals.class)); int numLeft = 0; if (fa.get(AAF_GUI.TIMEOUT)) { @@ -194,98 +196,114 @@ public class ApprovalForm extends Page { int endIndex = (beginIndicesPerApprover.isEmpty()?pendingApprovals.size():beginIndicesPerApprover.get(0)); List<Approval> currApproverList = pendingApprovals.subList(beginIndex, endIndex); - String currApproverFull = currApproverList.get(0).getApprover(); - String currApproverShort = currApproverFull.substring(0,currApproverFull.indexOf('@')); - String currApprover = (trans.user().indexOf('@')<0?currApproverShort:currApproverFull); - if (!currApprover.equals(trans.user())) { - AbsCell[] approverHeader; - if (currApproverFull.substring(currApproverFull.indexOf('@')).equals(DOMAIN_OF_USER)) { - approverHeader = new AbsCell[] { - new TextAndRefCell("Approvals Delegated to Me by ", currApprover, - TODO_ILM_INFO + currApproverShort, - true, - new String[] {"colspan=4", "class=head"}) - }; - } else { - approverHeader = new AbsCell[] { - new TextCell("Approvals Delegated to Me by " + currApprover, - new String[] {"colspan=4", "class=head"}) - }; - } - rv.add(approverHeader); - } - - // Sort by User Requesting - Collections.sort(currApproverList, new Comparator<Approval>() { - @Override - public int compare(Approval a1, Approval a2) { - return a1.getUser().compareTo(a2.getUser()); - } - }); - - String prevUser = null; - boolean userOK=true; - - for (Approval appr : currApproverList) { - if (++line<MAX_LINE) { // limit number displayed at one time. - AbsCell userCell; - String user = appr.getUser(); - if (user.equals(prevUser)) { - userCell = AbsCell.Null; - } else if (user.endsWith(DOMAIN_OF_USER)){ - userOK=true; - String title; - Organization org = OrganizationFactory.obtain(trans.env(), user); - if (org==null) { - title=""; - } else { - Identity au = org.getIdentity(trans, user); - if (au!=null) { - if ("MECHID".equals(au.type())) { - Identity managedBy = au.responsibleTo(); - if (managedBy==null) { - title ="title=" + au.type(); - } else { - title="title=Sponsor is " + managedBy.fullName(); - } - } else { - title="title=" + au.fullName(); - } - } else { - userOK=false; - title="title=Not a User at " + org.getName(); - } - } - prevUser=user; - userCell = new RefCell(prevUser, - TODO_ILM_INFO+user.substring(0, user.length()-DOMAIN_OF_USER.length()), - true, - title); - } else { - userCell = new TextCell(prevUser); - } - AbsCell[] sa = new AbsCell[] { - userCell, - new TextCell(appr.getMemo()), - userOK?new RadioCell("line."+ line,"approve", "approved|"+appr.getTicket()):new TextCell(""), - new RadioCell("line."+ line,"deny", "denied|"+appr.getTicket()) - }; - rv.add(sa); - } else { - ++numLeft; - } - } - } - if (numLeft>0) { - msg = "After these, there will be " + numLeft + " approvals left to process"; - } - if (rv.isEmpty()) { - if (numLeft>0) { - msg = "No Approvals to process at this time for user " + userParam +". You have " - + numLeft + " other approvals to process."; + Identity iapprover = trans.org().getIdentity(trans,currApproverList.get(0).getApprover()); + if(iapprover==null) { + rv.add(new AbsCell[] { + new TextCell(currApproverList.get(0).getApprover() + " is not part of Organization", + new String[] {"colspan=4", "class=head"}) + }); } else { - msg = "No Approvals to process at this time"; - } + if (!iapprover.fullID().equals(trans.user())) { + + AbsCell[] approverHeader; + // if (domainOfUser.equals(domainOfApprover)) { + // approverHeader = new AbsCell[] { + // new TextAndRefCell("Approvals Delegated to Me by ", currApproverFull, + // TODO_ILM_INFO + currApproverShort, + // true, + // new String[] {"colspan=4", "class=head"}) + // }; + // } else { + approverHeader = new AbsCell[] { + new TextCell("Approvals Delegated to Me by " + iapprover.fullName() + + '(' + iapprover.id() +')', + new String[] {"colspan=4", "class=head"}) + }; + // } + rv.add(approverHeader); + } + + // Sort by User Requesting + Collections.sort(currApproverList, new Comparator<Approval>() { + @Override + public int compare(Approval a1, Approval a2) { + return a1.getUser().compareTo(a2.getUser()); + } + }); + + String prevUser = null; + boolean userOK=true; + for (Approval appr : currApproverList) { + if (++line<MAX_LINE) { // limit number displayed at one time. + AbsCell userCell; + String user = appr.getUser(); + + if (user.equals(prevUser)) { + userCell = AbsCell.Null; + } else if (user.endsWith(trans.org().getRealm())){ + userOK=true; +// String title; + Organization org = OrganizationFactory.obtain(trans.env(), user); + if (org==null) { +// title=""; + userCell = new TextCell(user); + } else { + Identity au = org.getIdentity(trans, user); + if (au!=null) { + if(au.isPerson()) { + userCell = new TextCell(au.fullName() + "\n(" + au.id() + ')'); + } else { + userCell = new TextCell(au.fullID()); + } +// +// if ("MECHID".equals(au.type())) { +// Identity managedBy = au.responsibleTo(); +// if (managedBy==null) { +// title ="title=" + au.type(); +// } else { +// title="title=Sponsor is " + managedBy.fullName(); +// } +// } else { +// title="title=" + au.fullName(); +// } + } else { + userOK=false; +// title="title=Not a User at " + org.getName(); + userCell = new TextCell(user); + } + } + prevUser=user; + // userCell = new RefCell(prevUser, + // TODO_ILM_INFO+user.substring(0, user.length()-domainOfApprover.length()), + // true, + // title); + + } else { + userCell = new TextCell(prevUser==null?user:prevUser); + } + AbsCell[] sa = new AbsCell[] { + userCell, + new TextCell(appr.getMemo()), + userOK?new RadioCell("line."+ line,"approve", "approved|"+appr.getTicket()):new TextCell(""), + new RadioCell("line."+ line,"deny", "denied|"+appr.getTicket()) + }; + rv.add(sa); + } else { + ++numLeft; + } + } + } + if (numLeft>0) { + msg = "After these, there will be " + numLeft + " approvals left to process"; + } + if (rv.isEmpty()) { + if (numLeft>0) { + msg = "No Approvals to process at this time for user " + userParam +". You have " + + numLeft + " other approvals to process."; + } else { + msg = "No Approvals to process at this time"; + } + } } } catch (Exception e) { trans.error().log(e); diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java index c9730f5b..81a9d5ec 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java @@ -470,7 +470,7 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE } ) @Override - public Result<NSS> getNSbyName(AuthzTrans trans, String ns) { + public Result<NSS> getNSbyName(AuthzTrans trans, String ns, boolean includeExpired) { final Validator v = new ServiceValidator(); if (v.nullOrBlank("NS", ns).err()) { return Result.err(Status.ERR_BadData,v.errs()); @@ -488,11 +488,11 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE Namespace namespace = new Namespace(rnd.value); - Result<List<String>> rd = func.getOwners(trans, namespace.name, false); + Result<List<String>> rd = func.getOwners(trans, namespace.name, includeExpired); if (rd.isOK()) { namespace.owner = rd.value; } - rd = func.getAdmins(trans, namespace.name, false); + rd = func.getAdmins(trans, namespace.name, includeExpired); if (rd.isOK()) { namespace.admin = rd.value; } @@ -2731,6 +2731,7 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE cd.other = found.other; cd.type = found.type; cd.ns = found.ns; + cd.notes = "Extended"; cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime(); cd.tag = found.tag; @@ -4017,9 +4018,9 @@ public class AuthzCassServiceImpl <NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE cd.memo = ch.changed(cd.memo,updt.memo); cd.operation = ch.changed(cd.operation,updt.operation); cd.updated = ch.changed(cd.updated,updt.updated==null?new Date():updt.updated); - if (updt.status.equals("denied")) { - cd.last_notified = null; - } +// if (updt.status.equals("denied")) { +// cd.last_notified = null; +// } if (cd.ticket!=null) { FutureDAO.Data fdd = futureCache.get(cd.ticket); if (fdd==null) { // haven't processed ticket yet diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java index 6d4836d7..178e1aae 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzService.java @@ -127,7 +127,7 @@ public interface AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERT * @param ns * @return */ - public Result<NSS> getNSbyName(AuthzTrans trans, String ns); + public Result<NSS> getNSbyName(AuthzTrans trans, String ns, boolean full); /** * @@ -765,4 +765,6 @@ public interface AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERT public void dbReset(AuthzTrans trans); + + } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_NS.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_NS.java index 0c4a7e49..b06e3651 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_NS.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_NS.java @@ -181,7 +181,7 @@ public class API_NS { AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { - Result<Void> r = context.getNSsByName(trans, resp, pathParam(req,":id")); + Result<Void> r = context.getNSsByName(trans, resp, pathParam(req,":id"),TRUE.equals(req.getParameter(FULL))); switch(r.status) { case OK: resp.setStatus(HttpStatus.OK_200); diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java index 61a491f0..a08e958f 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java @@ -53,7 +53,7 @@ public interface AuthzFacade { */ public abstract Result<Void> requestNS(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, NsType type); - public abstract Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns); + public abstract Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns, boolean full); public abstract Result<Void> getNSsByAdmin(AuthzTrans trans, HttpServletResponse resp, String user, boolean full); 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 e77e0908..a2fb2209 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 @@ -472,10 +472,10 @@ public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE * @see com.att.authz.facade.AuthzFacade#getNSsByName(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String) */ @Override - public Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns) { + public Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns, boolean full) { TimeTaken tt = trans.start(GET_NS_BY_NAME + ' ' + ns, Env.SUB|Env.ALWAYS); try { - Result<NSS> rp = service.getNSbyName(trans, ns); + Result<NSS> rp = service.getNSbyName(trans, ns, full ); switch(rp.status) { case OK: RosettaData<NSS> data = nssDF.newData(trans).load(rp.value); diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java index daca47df..056651eb 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HClient.java @@ -40,7 +40,6 @@ import org.onap.aaf.cadi.SecuritySetter; import org.onap.aaf.cadi.client.EClient; import org.onap.aaf.cadi.client.Future; import org.onap.aaf.cadi.client.Rcli; -import org.onap.aaf.cadi.util.FixURIinfo; import org.onap.aaf.misc.env.APIException; import org.onap.aaf.misc.env.Data; import org.onap.aaf.misc.env.Data.TYPE; @@ -153,9 +152,9 @@ public class HClient implements EClient<HttpURLConnection> { throw e; } catch (Exception e) { if(sendURI==null) { - throw new APIException("Cannot connect to Root URI: " + uri.toString(),e); + throw new APIException("Cannot connect to Root URI: '" + uri.toString() + '\'',e); } else { - throw new APIException("Cannot connect to " + sendURI.toString() + "(Root URI: " + uri.toString() +')',e); + throw new APIException("Cannot connect to '" + sendURI.toString() + "' (Root URI: '" + uri.toString() + "')",e); } } finally { // ensure all these are reset after sends meth=pathinfo=null; diff --git a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HSecurityInfoInit.java b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HSecurityInfoInit.java index 68d0f209..7c7d391f 100644 --- a/cadi/client/src/main/java/org/onap/aaf/cadi/http/HSecurityInfoInit.java +++ b/cadi/client/src/main/java/org/onap/aaf/cadi/http/HSecurityInfoInit.java @@ -41,7 +41,7 @@ public class HSecurityInfoInit implements SecurityInfoInit<HttpURLConnection> { @Override public SecuritySetter<HttpURLConnection> bestDefault(SecurityInfoC<HttpURLConnection> si) throws CadiException { try { - if (si.defaultAlias!=null) { + if (si.defaultClientAlias!=null) { si.set(new HX509SS(si)); } else if (si.access.getProperty(Config.AAF_APPID, null)!=null && si.access.getProperty(Config.AAF_APPPASS, null)!=null) { diff --git a/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_HClientHotPeerLocator.java b/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_HClientHotPeerLocator.java index e40ecb6e..d85a84a2 100644 --- a/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_HClientHotPeerLocator.java +++ b/cadi/client/src/test/java/org/onap/aaf/cadi/locator/test/JU_HClientHotPeerLocator.java @@ -65,8 +65,8 @@ public class JU_HClientHotPeerLocator { assertThat(loc.hasItems(), is(true)); String[] messages = outStream.toString().split(System.lineSeparator()); - String preffered = messages[0].split(" ", 4)[3]; - String alternate = messages[1].split(" ", 4)[3]; + String preffered = messages[2].split(" ", 4)[3]; + String alternate = messages[3].split(" ", 4)[3]; assertThat(preffered, is("Preferred Client is " + goodURL1)); assertThat(alternate, is("Alternate Client is " + goodURL2)); @@ -98,9 +98,9 @@ public class JU_HClientHotPeerLocator { String urlStr = goodURL1 + ',' + goodURL2 + ',' + badURL; loc = new HClientHotPeerLocator(access, urlStr, 1000000, "38.627", "-90.199", ssMock); String[] messages = outStream.toString().split(System.lineSeparator()); - String preffered = messages[0].split(" ", 4)[3]; - String alternate1 = messages[1].split(" ", 4)[3]; - String alternate2 = messages[2].split(" ", 4)[3]; + String preffered = messages[2].split(" ", 4)[3]; + String alternate1 = messages[3].split(" ", 4)[3]; + String alternate2 = messages[4].split(" ", 4)[3]; assertThat(preffered, is("Preferred Client is " + badURL)); assertThat(alternate1, is("Alternate Client is " + goodURL1)); assertThat(alternate2, is("Alternate Client is " + goodURL2)); diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java index bbc3086a..2fe5f41c 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java @@ -37,6 +37,7 @@ import java.util.Properties; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.config.SecurityInfo; +import org.onap.aaf.cadi.util.Split; public class PropAccess implements Access { // Sonar says cannot be static... it's ok. not too many PropAccesses created. @@ -119,13 +120,21 @@ public class PropAccess implements Access { props.putAll(p); } - // Third, load any Chained Property Files - load(props.getProperty(Config.CADI_PROP_FILES)); - + // Preset LogLevel String sLevel = props.getProperty(Config.CADI_LOGLEVEL); if (sLevel!=null) { level=Level.valueOf(sLevel).maskOf(); } + + // Third, load any Chained Property Files + load(props.getProperty(Config.CADI_PROP_FILES)); + + if(sLevel==null) { // if LogLev wasn't set before, check again after Chained Load + sLevel = props.getProperty(Config.CADI_LOGLEVEL); + if (sLevel!=null) { + level=Level.valueOf(sLevel).maskOf(); + } + } // Setup local Symmetrical key encryption if (symm==null) { try { @@ -139,52 +148,41 @@ public class PropAccess implements Access { name = props.getProperty(Config.CADI_LOGNAME, name); - specialConversions(); + SecurityInfo.setHTTPProtocols(this); } - private void specialConversions() { - // Critical - if no Security Protocols set, then set it. We'll just get messed up if not - if (props.get(Config.CADI_PROTOCOLS)==null) { - props.setProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT); - } - - Object temp; - temp=props.get(Config.CADI_PROTOCOLS); - if (props.get(Config.HTTPS_PROTOCOLS)==null && temp!=null) { - props.put(Config.HTTPS_PROTOCOLS, temp); - } - - if (temp!=null) { - if ("1.7".equals(System.getProperty("java.specification.version")) - && (temp==null || (temp instanceof String && ((String)temp).contains("TLSv1.2")))) { - System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); - } - } - } - private void load(String cadi_prop_files) { if (cadi_prop_files==null) { return; } String prevKeyFile = props.getProperty(Config.CADI_KEYFILE); - int prev = 0, end = cadi_prop_files.length(); - int idx; - String filename; - while (prev<end) { - idx = cadi_prop_files.indexOf(File.pathSeparatorChar,prev); - if (idx<0) { - idx = end; - } - File file = new File(filename=cadi_prop_files.substring(prev,idx)); + + + for(String filename : Split.splitTrim(File.pathSeparatorChar, cadi_prop_files)) { + Properties fileProps = new Properties(); + File file = new File(filename); if (file.exists()) { printf(Level.INIT,"Loading CADI Properties from %s",file.getAbsolutePath()); try { FileInputStream fis = new FileInputStream(file); try { - props.load(fis); + fileProps.load(fis); + // Only load props from recursion which are not already in props + // meaning top Property file takes precedence + for(Entry<Object, Object> es : fileProps.entrySet()) { + if(props.get(es.getKey())==null) { + String key = es.getKey().toString(); + String value = es.getValue().toString(); + props.put(key, value); + if(key.contains("pass")) { + value = "XXXXXXX"; + } + printf(Level.DEBUG," %s=%s",key,value); + } + } // Recursively Load - String chainProp = props.getProperty(Config.CADI_PROP_FILES); + String chainProp = fileProps.getProperty(Config.CADI_PROP_FILES); if (chainProp!=null) { if (recursionProtection==null) { recursionProtection = new ArrayList<>(); @@ -204,7 +202,6 @@ public class PropAccess implements Access { } else { printf(Level.WARN,"Warning: recursive CADI Property %s does not exist",file.getAbsolutePath()); } - prev = idx+1; } // Trim @@ -244,8 +241,6 @@ public class PropAccess implements Access { printf(Level.ERROR,"%s=%s is an Invalid Log Level",Config.CADI_LOGLEVEL,loglevel); } } - - specialConversions(); } @Override diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java index 62623fb8..26305e91 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java @@ -92,6 +92,7 @@ public class Config { public static final String CADI_KEYSTORE = "cadi_keystore"; public static final String CADI_KEYSTORE_PASSWORD = "cadi_keystore_password"; public static final String CADI_ALIAS = "cadi_alias"; + public static final String CADI_CLIENT_ALIAS = "cadi_client_alias"; public static final String CADI_LOGINPAGE_URL = "cadi_loginpage_url"; public static final String CADI_LATITUDE = "cadi_latitude"; public static final String CADI_LONGITUDE = "cadi_longitude"; @@ -120,8 +121,9 @@ public class Config { public static final String CADI_TOKEN_DIR = "cadi_token_dir"; public static final String HTTPS_PROTOCOLS = "https.protocols"; - public static final String HTTPS_CIPHER_SUITES = "https.cipherSuites"; public static final String HTTPS_CLIENT_PROTOCOLS="jdk.tls.client.protocols"; + public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; + public static final String HTTPS_CIPHER_SUITES = "https.cipherSuites"; public static final String HTTPS_CIPHER_SUITES_DEFAULT="TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA," + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA," diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java index e3eb34be..285c45ec 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/SecurityInfo.java @@ -53,20 +53,23 @@ import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.util.MaskFormatException; import org.onap.aaf.cadi.util.NetMask; +import org.onap.aaf.cadi.util.Split; public class SecurityInfo { - private static final String SECURITY_ALGO = "RSA"; + private static final String SECURITY_ALGO = "RSA"; private static final String HTTPS_PROTOCOLS = "https.protocols"; private static final String JDK_TLS_CLIENT_PROTOCOLS = "jdk.tls.client.protocols"; + private static final String INITIALIZING_ERR_FMT = "Error initializing %s: %s"; + private static final String LOADED_FROM_CADI_PROPERTIES = "%s loaded from CADI Properties"; + private static final String LOADED_FROM_SYSTEM_PROPERTIES = "%s loaded from System Properties"; - public static final String HTTPS_PROTOCOLS_DEFAULT = "TLSv1.1,TLSv1.2"; - public static final String REGEX_COMMA = "\\s*,\\s*"; public static final String SSL_KEY_MANAGER_FACTORY_ALGORITHM; private SSLSocketFactory socketFactory; private X509KeyManager[] x509KeyManager; private X509TrustManager[] x509TrustManager; public final String defaultAlias; + public final String defaultClientAlias; private NetMask[] trustMasks; private SSLContext context; private HostnameVerifier maskHV; @@ -83,37 +86,81 @@ public class SecurityInfo { public SecurityInfo(final Access access) throws CadiException { + String msgHelp = ""; try { this.access = access; // reuse DME2 Properties for convenience if specific Properties don't exist + msgHelp = String.format(INITIALIZING_ERR_FMT,"Keystore", access.getProperty(Config.CADI_KEYSTORE, "")); initializeKeyManager(); + msgHelp = String.format(INITIALIZING_ERR_FMT,"Truststore", access.getProperty(Config.CADI_TRUSTSTORE, "")); initializeTrustManager(); - defaultAlias = access.getProperty(Config.CADI_ALIAS, null); + String str = access.getProperty(Config.CADI_ALIAS, null); + if(str==null || str.isEmpty()) { + defaultAlias = null; + } else { + defaultAlias = str; + } + + str = access.getProperty(Config.CADI_CLIENT_ALIAS, null); + if(str==null) { + defaultClientAlias = defaultAlias; + } else if(str.isEmpty()) { + // intentionally off, i.e. cadi_client_alias= + defaultClientAlias = null; + } else { + defaultClientAlias = str; + } + msgHelp = String.format(INITIALIZING_ERR_FMT,"Trustmasks", access.getProperty(Config.CADI_TRUST_MASKS, "")); initializeTrustMasks(); - String httpsProtocols = Config.logProp(access, Config.CADI_PROTOCOLS, - access.getProperty(HTTPS_PROTOCOLS, HTTPS_PROTOCOLS_DEFAULT) - ); - System.setProperty(HTTPS_PROTOCOLS, httpsProtocols); - System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, httpsProtocols); - if ("1.7".equals(System.getProperty("java.specification.version")) && httpsProtocols.contains("TLSv1.2")) { - System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT); - } - + msgHelp = String.format(INITIALIZING_ERR_FMT,"HTTP Protocols", "access properties"); + setHTTPProtocols(access); + + msgHelp = String.format(INITIALIZING_ERR_FMT,"Context", "TLS"); context = SSLContext.getInstance("TLS"); context.init(x509KeyManager, x509TrustManager, null); SSLContext.setDefault(context); socketFactory = context.getSocketFactory(); } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) { - throw new CadiException(e); + throw new CadiException(msgHelp,e); } } - /** + public static void setHTTPProtocols(Access access) { + String httpsProtocols = System.getProperty(Config.HTTPS_PROTOCOLS); + if(httpsProtocols!=null) { + access.printf(Level.INIT, LOADED_FROM_SYSTEM_PROPERTIES, HTTPS_PROTOCOLS); + } else { + httpsProtocols = access.getProperty(Config.HTTPS_PROTOCOLS,null); + if(httpsProtocols!=null) { + access.printf(Level.INIT, LOADED_FROM_CADI_PROPERTIES, HTTPS_PROTOCOLS); + } else { + httpsProtocols = access.getProperty(HTTPS_PROTOCOLS, Config.HTTPS_PROTOCOLS_DEFAULT); + access.printf(Level.INIT, "%s set by %s in CADI Properties",Config.HTTPS_PROTOCOLS,Config.CADI_PROTOCOLS); + } + // This needs to be set when people do not. + System.setProperty(HTTPS_PROTOCOLS, httpsProtocols); + } + String httpsClientProtocols = System.getProperty(JDK_TLS_CLIENT_PROTOCOLS,null); + if(httpsClientProtocols!=null) { + access.printf(Level.INIT, LOADED_FROM_SYSTEM_PROPERTIES, JDK_TLS_CLIENT_PROTOCOLS); + } else { + httpsClientProtocols = access.getProperty(Config.HTTPS_CLIENT_PROTOCOLS, null); + if(httpsClientProtocols!=null) { + access.printf(Level.INIT, LOADED_FROM_CADI_PROPERTIES, Config.HTTPS_CLIENT_PROTOCOLS); + } else { + httpsClientProtocols = Config.HTTPS_PROTOCOLS_DEFAULT; + access.printf(Level.INIT, "%s set from %s",Config.HTTPS_CLIENT_PROTOCOLS, "Default Protocols"); + } + System.setProperty(JDK_TLS_CLIENT_PROTOCOLS, httpsClientProtocols); + } + } + + /** * @return the scf */ public SSLSocketFactory getSSLSocketFactory() { @@ -172,7 +219,7 @@ public class SecurityInfo { ArrayList<X509KeyManager> keyManagers = new ArrayList<>(); File file; - for (String ksname : keyStore.split(REGEX_COMMA)) { + for (String ksname : Split.splitTrim(',', keyStore)) { String keystoreFormat; if (ksname.endsWith(".p12") || ksname.endsWith(".pkcs12")) { keystoreFormat = "PKCS12"; @@ -214,7 +261,7 @@ public class SecurityInfo { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(SSL_KEY_MANAGER_FACTORY_ALGORITHM); File file; - for (String trustStoreName : trustStore.split(REGEX_COMMA)) { + for (String trustStoreName : Split.splitTrim(',',trustStore)) { file = new File(trustStoreName); if (file.exists()) { FileInputStream fis = new FileInputStream(file); @@ -250,7 +297,7 @@ public class SecurityInfo { } access.log(Level.INIT, "Explicitly accepting valid X509s from", tips); - String[] ipsplit = tips.split(REGEX_COMMA); + String[] ipsplit = Split.splitTrim(',', tips); trustMasks = new NetMask[ipsplit.length]; for (int i = 0; i < ipsplit.length; ++i) { try { diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/util/CSV.java b/cadi/core/src/main/java/org/onap/aaf/cadi/util/CSV.java index a3958878..1d60ae58 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/util/CSV.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/util/CSV.java @@ -31,8 +31,8 @@ import java.util.ArrayList; import java.util.List; import org.onap.aaf.cadi.Access; -import org.onap.aaf.cadi.CadiException; import org.onap.aaf.cadi.Access.Level; +import org.onap.aaf.cadi.CadiException; /** * Read CSV file for various purposes @@ -156,11 +156,44 @@ public class CSV { return new Writer(append); } - public class Writer { + public interface RowSetter { + public void row(Object ... objs); + } + + public static class Saver implements RowSetter { + List<String> ls= new ArrayList<>(); + + @Override + public void row(Object ... objs) { + if(objs.length>0) { + for(Object o : objs) { + if(o != null) { + if(o instanceof String[]) { + for(String str : (String[])o) { + ls.add(str); + } + } else { + ls.add(o.toString()); + } + } + } + } + } + + public List<String> asList() { + List<String> rv = ls; + ls = new ArrayList<>(); + return rv; + } + } + + public class Writer implements RowSetter { private PrintStream ps; private Writer(final boolean append) throws FileNotFoundException { ps = new PrintStream(new FileOutputStream(csv,append)); } + + @Override public void row(Object ... objs) { if(objs.length>0) { boolean first = true; diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_Get.java b/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_Get.java index 982a29e5..b275790c 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_Get.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_Get.java @@ -68,27 +68,18 @@ public class JU_Get { @Test public void accessTest() { - String output; PropAccess access = new PropAccess(); access.setProperty("tag", "value"); Get.AccessGet accessGet = new Get.AccessGet(access); assertThat(accessGet.get("tag", defaultVal, true), is("value")); - output = outStream.toString().split(" ", 2)[1]; - assertThat(output, is("INIT [cadi] tag is set to value" + System.lineSeparator())); - outStream.reset(); assertThat(accessGet.get("not a real tag", defaultVal, true), is(defaultVal)); - output = outStream.toString().split(" ", 2)[1]; - assertThat(output, is("INIT [cadi] not a real tag is set to " + defaultVal + System.lineSeparator())); - outStream.reset(); assertThat(accessGet.get("not a real tag", null, true), is(nullValue())); - output = outStream.toString().split(" ", 2)[1]; - assertThat(output, is("INIT [cadi] not a real tag is not set" + System.lineSeparator())); outStream.reset(); diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_GetAccess.java b/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_GetAccess.java index 568a820c..c87b9c32 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_GetAccess.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_GetAccess.java @@ -73,11 +73,9 @@ public class JU_GetAccess { @SuppressWarnings("unused") GetAccess getAccess = new GetAccess(accessGet); String[] lines = outStream.toString().split(System.lineSeparator()); - assertThat(lines.length, is(2)); + assertThat(lines.length, is(6)); output = lines[0].split(" ", 2)[1]; - assertThat(output, is("INIT [cadi] cadi_prop_files is set to " + filePath)); - output = lines[1].split(" ", 2)[1]; - assertThat(output, is("INIT [cadi] Loading CADI Properties from " + filePath)); + } @Test diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_AbsUserCache.java b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_AbsUserCache.java index 8305be83..6ced3976 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_AbsUserCache.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_AbsUserCache.java @@ -108,24 +108,10 @@ public class JU_AbsUserCache { AbsUserCacheStub<Permission> aucs1 = new AbsUserCacheStub<Permission>(access, cleanInterval, maxInterval, Integer.MAX_VALUE); String output = outStream.toString().split(" ", 2)[1]; - StringBuilder expected = new StringBuilder(); - expected.append("INIT [cadi] Cleaning Thread initialized with interval of "); - expected.append(String.valueOf(cleanInterval)); - expected.append(" ms and max objects of "); - expected.append(String.valueOf(maxInterval)); - expected.append(System.lineSeparator()); - assertThat(output, is(expected.toString())); outStream.reset(); AbsUserCacheStub<Permission> aucs2 = new AbsUserCacheStub<Permission>(access, cleanInterval, maxInterval, Integer.MAX_VALUE); output = outStream.toString().split(" ", 2)[1]; - expected = new StringBuilder(); - expected.append("INIT [cadi] Cleaning Thread initialized with interval of "); - expected.append(String.valueOf(cleanInterval)); - expected.append(" ms and max objects of "); - expected.append(String.valueOf(maxInterval)); - expected.append(System.lineSeparator()); - assertThat(output, is(expected.toString())); AbsUserCacheStub<Permission> aucs3 = new AbsUserCacheStub<Permission>(access, 0, 0, Integer.MAX_VALUE); AbsUserCacheStub<Permission> aucs4 = new AbsUserCacheStub<Permission>(aucs1); diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_PropAccess.java b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_PropAccess.java index 45f221c4..9ab2c98d 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_PropAccess.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_PropAccess.java @@ -56,12 +56,6 @@ public class JU_PropAccess { } @Test - public void noLogItConstructionTest() throws Exception { - // Test for coverage - PropAccess prop = new PropAccess((LogIt)null, new String[]{"Invalid argument"}); - } - - @Test public void propertiesConstructionTest() throws Exception { // Coverage tests PropAccess prop = new PropAccess(System.getProperties()); diff --git a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_ServletContextAccess.java b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_ServletContextAccess.java index 7c67f8c9..104923c7 100644 --- a/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_ServletContextAccess.java +++ b/cadi/core/src/test/java/org/onap/aaf/cadi/test/JU_ServletContextAccess.java @@ -71,10 +71,6 @@ public class JU_ServletContextAccess { when(filter_mock.getInitParameterNames()).thenReturn(enumeration); } - @Test - public void ConstructorTest() throws Exception { - ServletContextAccess sca = new ServletContextAccess(filter_mock); - } @Test public void logTest() throws Exception { diff --git a/version.properties b/version.properties index 913ef770..cada72b1 100644 --- a/version.properties +++ b/version.properties @@ -19,13 +19,15 @@ # ============LICENSE_END============================================ ### + # Versioning variables # Note that these variables cannot be structured (e.g. : version.release or version.snapshot etc... ) # because they are used in Jenkins, whose plug-in doesn't support +# This TAG <version>2.1.10</version> is here to help remember to change this file. Keep it up to date with the following "real" entries: major=2 minor=1 -patch=9 +patch=10 base_version=${major}.${minor}.${patch} |