Approval Batch, prep better JUnit 53/77753/1
authorInstrumental <jonathan.gathman@att.com>
Sun, 3 Feb 2019 12:09:34 +0000 (06:09 -0600)
committerInstrumental <jonathan.gathman@att.com>
Sun, 3 Feb 2019 12:09:46 +0000 (06:09 -0600)
Issue-ID: AAF-740
Change-Id: Id9e8ca121c9bf92c2f98c7a61631e2417bba70b1
Signed-off-by: Instrumental <jonathan.gathman@att.com>
57 files changed:
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/ApprovalAdd.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/FutureAdd.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/NSDescUpdate.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/PermModify.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/RoleCreate.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/RoleDelete.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/RoleModify.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/URFutureApproveExec.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/ApprovalSet.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/DataView.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Loader.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/URApprovalSet.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Approval.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/BatchDataView.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/ExpireRange.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Future.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/NS.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Role.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/UserRole.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Expiring.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/NotInOrg.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/Notify.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/reports/NsRoleUserReport.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Approvals.java [new file with mode: 0644]
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/NotifyCredExpiring.java
auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/update/Remove.java
auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/FutureDAO.java
auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/UserRoleDAO.java
auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java
auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/Facade.java
auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/facade/FacadeImpl.java
auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper.java
auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper1_0.java
auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java
auth/auth-certman/src/test/java/org/onap/aaf/auth/cm/JU_AAF_CM.java
auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java
auth/auth-core/src/main/java/org/onap/aaf/auth/layer/Result.java
auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/facade/OAFacade.java
auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/facade/OAFacadeImpl.java
auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/mapper/Mapper.java
auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/mapper/Mapper1_0.java
auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java
cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFSingleLocator.java
cadi/aaf/src/main/java/org/onap/aaf/cadi/aaf/v2_0/AAFTaf.java
cadi/core/src/main/java/org/onap/aaf/cadi/taf/basic/BasicHttpTaf.java
cadi/core/src/main/java/org/onap/aaf/cadi/util/CSV.java
cadi/core/src/main/java/org/onap/aaf/cadi/util/Vars.java
cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_MapBathConverter.java
cadi/core/src/test/java/org/onap/aaf/cadi/config/test/JU_RegistrationPropHolder.java
cadi/core/src/test/java/org/onap/aaf/cadi/util/test/JU_CSV.java
misc/env/src/main/java/org/onap/aaf/misc/env/Env.java
misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java
misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java
misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicEnv.java
misc/env/src/main/java/org/onap/aaf/misc/env/impl/BasicTrans.java
misc/env/src/test/java/org/onap/aaf/misc/env/impl/JU_AbsTrans.java
misc/env/src/test/java/org/onap/aaf/misc/env/impl/JU_AbsTransJaxb.java

diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/ApprovalAdd.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/ApprovalAdd.java
new file mode 100644 (file)
index 0000000..f31de56
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * ============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.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.batch.helpers.Approval;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class ApprovalAdd extends ActionDAO<Approval,ApprovalDAO.Data,String> {
+    public ApprovalAdd(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+        super(trans, cluster,dryRun);
+    }
+    
+    public ApprovalAdd(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+        super(trans, adao);
+    }
+
+    @Override
+    public Result<ApprovalDAO.Data> exec(AuthzTrans trans, Approval app, String text) {
+       return exec(trans,app.add,text);
+    }
+
+    public Result<ApprovalDAO.Data> exec(AuthzTrans trans, ApprovalDAO.Data add, String text) {
+       if (dryRun) {
+            trans.info().log("Would Add:",text,add.approver,add.memo);
+            return Result.ok(add);
+        } else {
+            Result<ApprovalDAO.Data> rv = q.approvalDAO.create(trans, add);
+            trans.info().log("Added:",text,add.approver,add.memo);
+            return rv;
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/FutureAdd.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/actions/FutureAdd.java
new file mode 100644 (file)
index 0000000..29a500c
--- /dev/null
@@ -0,0 +1,59 @@
+/**
+ * ============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.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.batch.helpers.Future;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class FutureAdd extends ActionDAO<Future,FutureDAO.Data,String> {
+    public FutureAdd(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+        super(trans, cluster,dryRun);
+    }
+    
+    public FutureAdd(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+        super(trans, adao);
+    }
+
+    @Override
+    public Result<FutureDAO.Data> exec(AuthzTrans trans, Future f, String text) {
+       return exec(trans,f.fdd,text);
+    }
+       
+    public Result<FutureDAO.Data> exec(AuthzTrans trans, FutureDAO.Data fdd, String text) {
+        if (dryRun) {
+            trans.info().log("Would Add:",text,fdd.id, fdd.memo);
+            return Result.ok(fdd);
+        } else {
+            Result<FutureDAO.Data> rv = q.futureDAO.create(trans, fdd);
+            trans.info().log("Added:",text,fdd.id, fdd.memo);
+            return rv;
+        }
+    }
+    
+}
\ No newline at end of file
index 2542e04..78e835b 100644 (file)
@@ -45,7 +45,7 @@ public class NSDescUpdate extends ActionDAO<NS,Void,String> {
             trans.info().printf("Would Update '%s' Description to '%s'",ns,desc);
             return Result.ok();
         } else {
-            Result<Void> rv = q.nsDAO.dao().addDescription(trans, ns.name, desc);
+            Result<Void> rv = q.nsDAO.dao().addDescription(trans, ns.ndd.name, desc);
             if (rv.isOK()) {
                 trans.info().printf("Updated '%s' Description to '%s'",ns,desc);
             } else {
index 4b76baf..58dd6fb 100644 (file)
@@ -76,7 +76,7 @@ public class PermModify extends ActionDAO<Perm,PermDAO.Data,PermModify.Modify> {
                     } else {
                         for (String r : d.roles) {
                             Role role = Role.keys.get(r);
-                            if (role.perms.contains(p.encode())) {
+                            if (role.rdd.perms.contains(p.encode())) {
                                 modify.roleModify().exec(trans, role, new RoleModify.Modify() {
                                     @Override
                                     public PermModify permModify() {
index 512d4a3..729d5c1 100644 (file)
@@ -24,7 +24,6 @@ package org.onap.aaf.auth.batch.actions;
 import java.io.IOException;
 
 import org.onap.aaf.auth.batch.helpers.Role;
-import org.onap.aaf.auth.dao.cass.RoleDAO;
 import org.onap.aaf.auth.dao.cass.RoleDAO.Data;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
@@ -43,17 +42,11 @@ public class RoleCreate extends ActionDAO<Role,Data,String> {
 
     @Override
     public Result<Data> exec(AuthzTrans trans, Role r,String text) {
-        RoleDAO.Data rdd = new RoleDAO.Data();
-        rdd.ns = r.ns;
-        rdd.name = r.name;
-        rdd.description = r.description;
-        rdd.perms = r.perms;
-        
         if (dryRun) {
             trans.info().log("Would Create Role:",text,r.fullName());
-            return Result.ok(rdd);
+            return Result.ok(r.rdd);
         } else {
-            Result<Data> rv = q.roleDAO.create(trans, rdd); // need to read for undelete
+            Result<Data> rv = q.roleDAO.create(trans, r.rdd); // need to read for undelete
             if (rv.isOK()) {
                 trans.info().log("Created Role:",text,r.fullName());
             } else {
index 3e109b2..edaae0f 100644 (file)
@@ -24,7 +24,6 @@ package org.onap.aaf.auth.batch.actions;
 import java.io.IOException;
 
 import org.onap.aaf.auth.batch.helpers.Role;
-import org.onap.aaf.auth.dao.cass.RoleDAO;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
 import org.onap.aaf.misc.env.APIException;
@@ -46,10 +45,7 @@ public class RoleDelete extends ActionDAO<Role,Void,String> {
             trans.info().log("Would Delete Role:",text,r.fullName());
             return Result.ok();
         } else {
-            RoleDAO.Data rdd = new RoleDAO.Data();
-            rdd.ns = r.ns;
-            rdd.name = r.name;
-            Result<Void> rv = q.roleDAO.delete(trans, rdd, true); // need to read for undelete
+            Result<Void> rv = q.roleDAO.delete(trans, r.rdd, true); // need to read for undelete
             if (rv.isOK()) {
                 trans.info().log("Deleted Role:",text,r.fullName());
             } else {
index 388e669..e00c08c 100644 (file)
@@ -47,7 +47,7 @@ public class RoleModify extends ActionDAO<Role,RoleDAO.Data,RoleModify.Modify> {
 
     @Override
     public Result<RoleDAO.Data> exec(final AuthzTrans trans, final Role r,final RoleModify.Modify modify) {
-        Result<List<Data>> rr = q.roleDAO.read(trans, r.ns,r.name);
+        Result<List<Data>> rr = q.roleDAO.read(trans, r.rdd.ns,r.rdd.name);
         if (dryRun) {
             if (rr.isOKhasData()) {
                 return Result.ok(rr.value.get(0));
@@ -59,18 +59,18 @@ public class RoleModify extends ActionDAO<Role,RoleDAO.Data,RoleModify.Modify> {
             if (rr.isOKhasData()) {
                 for (final Data d : rr.value) {
                     modify.change(d);
-                    if (d.ns.equals(r.ns) && d.name.equals(r.name)) {
+                    if (d.ns.equals(r.rdd.ns) && d.name.equals(r.rdd.name)) {
                         // update for fields
                         // In either case, adjust Roles
                         for (String p : d.perms) {
-                            if (!r.perms.contains(p)) {
+                            if (!r.rdd.perms.contains(p)) {
                                 Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans, q, p);
                                 if (rpdd.isOKhasData()) {
                                     q.roleDAO.dao().addPerm(trans, d, rpdd.value);
                                 }
                             }
                         }
-                        for (String p : r.perms) {
+                        for (String p : r.rdd.perms) {
                             if (!d.perms.contains(p)) {
                                 Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans, q, p);
                                 if (rpdd.isOKhasData()) {
@@ -113,11 +113,8 @@ public class RoleModify extends ActionDAO<Role,RoleDAO.Data,RoleModify.Modify> {
                             rv = q.roleDAO.create(trans, d);
                         }
                         if (rv.isOK()) {
-                            trans.info().printf("Updating %s|%s to %s|%s", r.ns, r.name, d.ns, d.name);
-                            RoleDAO.Data rmme = new RoleDAO.Data();
-                            rmme.ns=r.ns;
-                            rmme.name=r.name;
-                            q.roleDAO.delete(trans, rmme, false);
+                            trans.info().printf("Updating %s|%s to %s|%s", r.rdd.ns, r.rdd.name, d.ns, d.name);
+                            q.roleDAO.delete(trans, r.rdd, false);
                             
                         } else {
                             trans.info().log(rv.errorString());
@@ -143,10 +140,7 @@ public class RoleModify extends ActionDAO<Role,RoleDAO.Data,RoleModify.Modify> {
         if (dryRun) {
             return Result.ok();
         } else {
-            RoleDAO.Data data = new RoleDAO.Data();
-            data.ns=r.ns;
-            data.name = r.name;
-            return q.roleDAO.delete(trans,data,false);
+            return q.roleDAO.delete(trans,r.rdd,false);
         }
     }
 }
\ No newline at end of file
index 6636f45..9c44a62 100644 (file)
@@ -30,9 +30,7 @@ import org.onap.aaf.auth.batch.helpers.Future;
 import org.onap.aaf.auth.batch.helpers.UserRole;
 import org.onap.aaf.auth.dao.cass.ApprovalDAO;
 import org.onap.aaf.auth.dao.cass.UserRoleDAO;
-import org.onap.aaf.auth.dao.cass.ApprovalDAO.Data;
 import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
-import org.onap.aaf.auth.dao.hl.Function.Lookup;
 import org.onap.aaf.auth.dao.hl.Function.OP_STATUS;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/ApprovalSet.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/ApprovalSet.java
new file mode 100644 (file)
index 0000000..eeeef15
--- /dev/null
@@ -0,0 +1,96 @@
+/**
+ * ============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.approvalsets;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.UUID;
+
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class ApprovalSet {
+       private DataView dataview;
+       protected FutureDAO.Data fdd;
+       protected List<ApprovalDAO.Data> ladd;
+       
+       public ApprovalSet(final GregorianCalendar start, final String target, final DataView dv) throws CadiException {
+               dataview = dv;
+               fdd = new FutureDAO.Data();
+        try {
+                       fdd.id = newID(target);
+               } catch (NoSuchAlgorithmException e) {
+                       throw new CadiException(e);
+               } 
+               fdd.target = target;
+               fdd.start = start.getTime();
+               ladd = new ArrayList<>();
+       }
+       
+       protected UUID newID(String target) throws NoSuchAlgorithmException {
+               StringBuilder sb = new StringBuilder(new String(SecureRandom.getInstanceStrong().generateSeed(10)));
+        sb.append(target);
+        sb.append(System.currentTimeMillis());
+        return Chrono.dateToUUID(System.currentTimeMillis());
+       }
+
+       protected void setConstruct(final ByteBuffer bytes) {
+               fdd.construct = bytes;
+       }
+
+       protected void setMemo(final String memo) {
+               fdd.memo = memo;
+       }
+       
+       protected void setExpires(final GregorianCalendar expires) {
+               fdd.expires = expires.getTime();
+       }
+       
+       public Result<Void> write(AuthzTrans trans) {
+               StringBuilder errs = null;
+               Result<FutureDAO.Data> rf = dataview.write(trans, fdd);
+               if(rf.notOK()) {
+                       errs = new StringBuilder();
+                       errs.append(rf.errorString());
+               } else {
+                       for(ApprovalDAO.Data add : ladd) {
+                               Result<ApprovalDAO.Data> af = dataview.write(trans, add);
+                               if(af.notOK()) {
+                                       if(errs==null) {
+                                               errs = new StringBuilder();
+                                       } else {
+                                               errs.append('\n');
+                                       }
+                                       errs.append(af.errorString());
+                               }
+                       }
+               }
+               return errs==null?Result.ok():Result.err(Result.ERR_Backend,errs.toString());
+       }
+}
\ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/DataView.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/DataView.java
new file mode 100644 (file)
index 0000000..73e7983
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * ============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.approvalsets;
+
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.cass.NsDAO;
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+
+/**
+ * I have become convinced that Data for Apps is modeled by abstract access methods against multiple data
+ * sources.  With the insistence of JUnits, it becomes much more paramount to create a model which can 
+ *   1) be easily loaded from Disk "Test Data" without resorting to complex "mokito" schemes
+ *   2) tested in Memory
+ *   3) combined for REAL time by running Cached Memory
+ *   4) Streamable in
+ *     a) Binary
+ *      b) CSV
+ *      c) JSON
+ *      d) XML
+ *   5) persisted Globally through a store like Cassandra
+ *   
+ * But in the end, it looks like:
+ *   1) Data Structures
+ *   2) Find the Data Structures by various means, accounting for 
+ *     a) Multiple Responses
+ *      b) Errors from the deepest level, made available through the call stack
+ *   3) 
+ *     
+ * @author jonathan.gathman
+ *
+ */
+public interface DataView {
+       // Reads
+       public Result<NsDAO.Data> ns(final AuthzTrans trans, final String id);
+       public Result<RoleDAO.Data> roleByName(final AuthzTrans trans, final String name);
+       public Result<List<UserRoleDAO.Data>> ursByRole(final AuthzTrans trans, final String role);
+       public Result<List<UserRoleDAO.Data>> ursByUser(final AuthzTrans trans, final String user);
+
+       // Writes
+       public Result<ApprovalDAO.Data> write(final AuthzTrans trans, final ApprovalDAO.Data add);
+       public Result<FutureDAO.Data> write(final AuthzTrans trans, final FutureDAO.Data add);
+       
+       // Deletes
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Loader.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/approvalsets/Loader.java
new file mode 100644 (file)
index 0000000..806599e
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * ============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.approvalsets;
+
+import org.onap.aaf.cadi.CadiException;
+
+public interface Loader<T> {
+       public T load() throws CadiException;
+}
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
new file mode 100644 (file)
index 0000000..b6767d4
--- /dev/null
@@ -0,0 +1,125 @@
+/**
+ * ============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.approvalsets;
+
+import java.io.IOException;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.NsDAO;
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.Organization.Identity;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class URApprovalSet extends ApprovalSet {
+       public static final String EXTEND_STRING = "Extend access of User [%s] to Role [%s] - Expires %s";
+       
+       public URApprovalSet(final AuthzTrans trans, final GregorianCalendar start, final DataView dv, final Loader<UserRoleDAO.Data> lurdd) throws IOException, CadiException {
+               super(start, "user_role", dv);
+               Organization org = trans.org();
+               UserRoleDAO.Data urdd = lurdd.load();
+               setConstruct(urdd.bytify());
+               setMemo(String.format(EXTEND_STRING,urdd.user,urdd.role,Chrono.dateOnlyStamp(urdd.expires)));
+               setExpires(org.expiration(null, Organization.Expiration.UserInRole));
+               
+               Result<RoleDAO.Data> r = dv.roleByName(trans, urdd.role);
+               if(r.notOKorIsEmpty()) {
+                       throw new CadiException(String.format("Role '%s' does not exist: %s", urdd.role, r.details));
+               }
+               Result<NsDAO.Data> n = dv.ns(trans, urdd.ns);
+               if(n.notOKorIsEmpty()) {
+                       throw new CadiException(String.format("Namespace '%s' does not exist: %s", urdd.ns));
+               }
+               UserRoleDAO.Data found = null;
+               Result<List<Data>> lur = dv.ursByRole(trans, urdd.role);
+               if(lur.isOK()) {
+                       for(UserRoleDAO.Data ur : lur.value) {
+                               if(urdd.user.equals(ur.user)) {
+                                       found = ur;
+                                       break;
+                               }
+                       }
+               }
+               if(found==null) {
+                       throw new CadiException(String.format("User '%s' in Role '%s' does not exist: %s", urdd.user,urdd.role));
+               }
+               
+               // Primarily, Owners are responsible, unless it's owned by self
+               boolean isOwner = false;
+               Result<List<UserRoleDAO.Data>> owners = dv.ursByRole(trans, urdd.ns+".owner");
+               if(owners.isOK()) {
+                       for(UserRoleDAO.Data owner : owners.value) {
+                               if(urdd.user.equals(owner.user)) {
+                                       isOwner = true;
+                               } else {
+                                       ApprovalDAO.Data add = newApproval(urdd);
+                                       add.approver = owner.user;
+                                       add.type="owner";
+                                       ladd.add(add);
+                               }
+                       }
+               }
+
+               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.type = org.getApproverType();
+                                               ladd.add(add);
+                                       }
+                               }
+                       } catch (OrganizationException e) {
+                               throw new CadiException(e);
+                       }
+               }
+       }
+
+       private ApprovalDAO.Data newApproval(Data urdd) throws CadiException {
+               ApprovalDAO.Data add = new ApprovalDAO.Data();
+               add.id = Chrono.dateToUUID(System.currentTimeMillis());
+               add.ticket = fdd.id;
+               add.user = urdd.user;
+               add.operation = FUTURE_OP.A.name();
+               add.status = ApprovalDAO.PENDING;
+               add.memo = String.format("Re-Validate as Owner for AAF Namespace '%s' - expiring %s', ",
+                                  urdd.ns,
+                                  Chrono.dateOnlyStamp(urdd.expires));
+               return add;
+       }
+
+}
index fb3aefb..acaf0d5 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.aaf.auth.batch.helpers;
 
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.Iterator;
 import java.util.List;
 import java.util.TreeMap;
 import java.util.UUID;
@@ -30,6 +31,7 @@ import java.util.UUID;
 import org.onap.aaf.auth.dao.cass.ApprovalDAO;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.cadi.util.CSV;
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.env.Trans;
@@ -90,6 +92,41 @@ public class Approval implements CacheChange.Data  {
         return null;
     }
 
+    public static void load(Trans trans, Session session, Creator<Approval> creator, Visitor<Approval> visitor) {
+        trans.info().log( "query: " + creator.select() );
+        TimeTaken tt = trans.start("Read Approval", Env.REMOTE);
+       
+        ResultSet results;
+        try {
+            Statement stmt = new SimpleStatement( creator.select() );
+            results = session.execute(stmt);
+        } finally {
+            tt.done();
+        }
+
+        int count = 0;
+        try {
+            Iterator<Row> iter = results.iterator();
+            Row row;
+            tt = trans.start("Load X509s", Env.SUB);
+            try {
+                while (iter.hasNext()) {
+                       ++count;
+                    row = iter.next();
+                    visitor.visit(creator.create(row));
+                }
+            } finally {
+                tt.done();
+            }
+        } finally {
+            trans.info().log("Found",count,"X509 Certificates");
+        }
+    }
+    
+       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 load(Trans trans, Session session, Creator<Approval> creator ) {
         trans.info().log( "query: " + creator.select() );
         TimeTaken tt = trans.start("Load Notify", Env.REMOTE);
@@ -306,4 +343,10 @@ public class Approval implements CacheChange.Data  {
         return cache.contains(a);
     }
 
+       public static void deleteByIDBatch(StringBuilder sb, String id) {
+               sb.append("DELETE from authz.approval where id=");
+               sb.append(id);
+               sb.append(";\n");
+       }
+
 }
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
new file mode 100644 (file)
index 0000000..e934bda
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * ============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.helpers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.aaf.auth.batch.actions.ApprovalAdd;
+import org.onap.aaf.auth.batch.actions.FutureAdd;
+import org.onap.aaf.auth.batch.approvalsets.DataView;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.cass.NsDAO;
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public class BatchDataView implements DataView {
+       private FutureAdd futureAdd;
+       private ApprovalAdd approvalAdd;
+
+       public BatchDataView(final AuthzTrans trans, final Cluster cluster, final boolean dryRun ) throws APIException, IOException {
+               futureAdd = new FutureAdd(trans, cluster, dryRun);
+               approvalAdd = new ApprovalAdd(trans, futureAdd);
+       }
+
+       public Session getSession(AuthzTrans trans) throws APIException, IOException {
+               TimeTaken tt = trans.start("Get Session", Trans.SUB);
+               try {
+                       return futureAdd.getSession(trans);
+               } finally {
+                       tt.done();
+               }
+       }
+       
+       public Result<NsDAO.Data> ns(AuthzTrans trans, String id) {
+               NS n;
+               TimeTaken tt = trans.start("Get NS by ID %s", Trans.SUB, id);
+               try {
+                       n=NS.data.get(id);
+               } finally {
+                       tt.done();
+               }
+               
+               if(n==null || n.ndd==null) {
+                       return Result.err(Result.ERR_Backend,"Namespace '%s' does not exist", id);
+               }
+               return Result.ok(n.ndd);
+       }
+
+       
+       @Override
+       public Result<RoleDAO.Data> roleByName(AuthzTrans trans, String name) {
+               Role r = Role.byName.get(name);
+               if(r==null || r.rdd==null) {
+                       return Result.err(Result.ERR_Backend,"Role '%s' does not exist", name);
+               }
+               return Result.ok(r.rdd);
+       }
+
+       @Override
+       public Result<List<UserRoleDAO.Data>> ursByRole(AuthzTrans trans, String role) {
+               List<UserRole> urs = UserRole.getByRole().get(role);
+               if(urs==null) {
+                       return Result.err(Result.ERR_Backend, "UserRoles for Role '%s' does not exist", role);
+               }
+               return toLURDD(urs);
+       }
+
+       private Result<List<Data>> toLURDD(List<UserRole> urs) {
+               List<UserRoleDAO.Data> rv = new ArrayList<>();
+               if(urs!=null) {
+                       for(UserRole ur : urs) {
+                               rv.add(ur.urdd());
+                       }
+               }
+               return Result.ok(rv);
+       }
+
+       @Override
+       public Result<List<UserRoleDAO.Data>> ursByUser(AuthzTrans trans, String user) {
+               List<UserRole> urs = UserRole.getByUser().get(user);
+               if(urs==null) {
+                       return Result.err(Result.ERR_Backend, "UserRoles for User '%s' does not exist", user);
+               }
+               return toLURDD(urs);
+       }
+
+       @Override
+       public Result<FutureDAO.Data> write(AuthzTrans trans, FutureDAO.Data fdd) {
+               return futureAdd.exec(trans, fdd, null);
+       }
+
+       @Override
+       public Result<ApprovalDAO.Data> write(AuthzTrans trans, ApprovalDAO.Data add) {
+               return approvalAdd.exec(trans, add, null);
+       }
+
+}
index c459dc6..b06cbce 100644 (file)
@@ -38,6 +38,7 @@ public class ExpireRange {
        public Map<String,List<Range>> ranges;
        public final Date now;
        public String rangeOneMonth = "OneMonth";
+       private Range delRange;
        
        public ExpireRange(final Access access) {
                now = new Date();
@@ -49,10 +50,10 @@ public class ExpireRange {
                                List<Range> lur = getRangeList("ur");
                                List<Range> lx509 = getRangeList("x509");
                                
-                               Range del = new Range("Delete",0,0,-1,0,GregorianCalendar.WEEK_OF_MONTH,-2);
-                               lur.add(del);
-                               lcred.add(del);
-                               lx509.add(del);
+                               delRange = new Range("Delete",0,0,-1,0,GregorianCalendar.WEEK_OF_MONTH,-2);
+                               lur.add(delRange);
+                               lcred.add(delRange);
+                               lx509.add(delRange);
                                
                                lcred.add(new Range("CredOneWeek",3,1,0,0,GregorianCalendar.WEEK_OF_MONTH,1));
                                lcred.add(new Range("CredTwoWeek",2,1,GregorianCalendar.WEEK_OF_MONTH,1,GregorianCalendar.WEEK_OF_MONTH,2));
index d9ee272..13f8193 100644 (file)
@@ -34,6 +34,7 @@ import java.util.UUID;
 import org.onap.aaf.auth.dao.cass.FutureDAO;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.cadi.util.CSV;
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.env.Trans;
@@ -111,8 +112,27 @@ public class Future implements CacheChange.Data, Comparable<Future> {
     public final Date expires() {
         return fdd.expires;
     }
-
+    
     public static void load(Trans trans, Session session, Creator<Future> creator) {
+       load(trans,session,creator, new Visitor<Future>() {
+                       @Override
+                       public void visit(Future f) {
+                           data.put(f.fdd.id,f);
+                           if (f.role==null) {
+                               return;
+                           }
+                           List<Future> lf = byRole.get(f.role);
+                           if (lf==null) {
+                               lf = new ArrayList<>();
+                               byRole.put(f.role,lf);
+                           }
+                           lf.add(f);
+                       }
+               });
+    }
+
+
+    public static void load(Trans trans, Session session, Creator<Future> creator, Visitor<Future> visitor) {
         trans.info().log( "query: " + creator.select() );
         ResultSet results;
         TimeTaken tt = trans.start("Load Futures", Env.REMOTE);
@@ -127,19 +147,8 @@ public class Future implements CacheChange.Data, Comparable<Future> {
         tt = trans.start("Process Futures", Env.SUB);
         try {
             for (Row row : results.all()) {
-                ++count;
-                Future f = creator.create(row);
-                data.put(f.fdd.id,f);
-                if (f.role==null) {
-                    continue;
-                }
-                List<Future> lf = byRole.get(f.role);
-                if (lf==null) {
-                    lf = new ArrayList<>();
-                    byRole.put(f.role,lf);
-                }
-                lf.add(f);
-
+                   ++count;
+               visitor.visit(creator.create(row));
             }
         } finally {
             tt.done();
@@ -199,6 +208,16 @@ public class Future implements CacheChange.Data, Comparable<Future> {
     public static boolean pendingDelete(Future f) {
         return cache.contains(f);
     }
+    
+       public static void row(CSV.Writer cw, Future f) {
+               cw.row("future",f.fdd.id,f.fdd.target,f.fdd.expires,f.role,f.fdd.memo);
+       }
+
 
+       public static void deleteByIDBatch(StringBuilder sb, String id) {
+               sb.append("DELETE from authz.future where id=");
+               sb.append(id);
+               sb.append(";\n");
+       }
 
 }
index cad1c12..55fe22c 100644 (file)
@@ -27,6 +27,7 @@ import java.util.Iterator;
 import java.util.Map;
 import java.util.TreeMap;
 
+import org.onap.aaf.auth.dao.cass.NsDAO;
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.env.Trans;
@@ -40,11 +41,7 @@ import com.datastax.driver.core.Statement;
 public class    NS implements Comparable<NS> {
     public static final Map<String,NS> data = new TreeMap<>();
 
-    public final String name;
-    public final String description;
-    public final String parent;
-    public final int scope;
-    public final int type;
+    public NsDAO.Data ndd;
 
     public static Creator<NS> v2_0_11 = new Creator<NS> () {
         @Override
@@ -59,11 +56,12 @@ public class    NS implements Comparable<NS> {
     };
 
     public NS(String name, String description, String parent, int type, int scope) {
-        this.name = name;
-        this.description = description;
-        this.parent = parent;
-        this.scope = scope;
-        this.type = type;
+       ndd = new NsDAO.Data();
+        ndd.name = name;
+        ndd.description = description;
+        ndd.parent = parent;
+        ndd.type = type;
+        // ndd.attrib = 
     }
     
     public static void load(Trans trans, Session session, Creator<NS> creator) {
@@ -101,7 +99,7 @@ public class    NS implements Comparable<NS> {
                 while (iter.hasNext()) {
                     row = iter.next();
                     NS ns = creator.create(row);
-                    data.put(ns.name,ns);
+                    data.put(ns.ndd.name,ns);
                 }
             } finally {
                 tt.done();
@@ -127,7 +125,7 @@ public class    NS implements Comparable<NS> {
     }
         
     public String toString() {
-        return name;
+        return ndd.name;
     }
 
     /* (non-Javadoc)
@@ -135,7 +133,7 @@ public class    NS implements Comparable<NS> {
      */
     @Override
     public int hashCode() {
-        return name.hashCode();
+        return ndd.name.hashCode();
     }
 
     /* (non-Javadoc)
@@ -143,12 +141,12 @@ public class    NS implements Comparable<NS> {
      */
     @Override
     public boolean equals(Object obj) {
-        return name.equals(obj);
+        return ndd.name.equals(obj);
     }
 
     @Override
     public int compareTo(NS o) {
-        return name.compareTo(o.name);
+        return ndd.name.compareTo(o.ndd.name);
     }
     
     public static class NSSplit {
@@ -171,5 +169,4 @@ public class    NS implements Comparable<NS> {
         return null;
     }
 
-        
 }
\ No newline at end of file
index 6d87ded..ea735d2 100644 (file)
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.TreeMap;
 
+import org.onap.aaf.auth.dao.cass.RoleDAO;
 import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.TimeTaken;
 import org.onap.aaf.misc.env.Trans;
@@ -46,38 +47,39 @@ public class Role implements Comparable<Role> {
     public static final TreeMap<String,Role> byName = new TreeMap<>();
     private static List<Role> deleteRoles = new ArrayList<>();
 
-    public final String ns;
-    public final String name;
-    public final String description;
+    public RoleDAO.Data rdd;
     private String full;
     private String encode;
-    public final Set<String> perms;
     
     public Role(String full) {
-        ns = name = description = "";
+       rdd = new RoleDAO.Data();
+        rdd.ns = "";
+        rdd.name = "";
+        rdd.description = "";
+        rdd.perms = new HashSet<>();
         this.full = full;
-        perms = new HashSet<>();
     }
     
     public Role(String ns, String name, String description,Set<String> perms) {
-        this.ns = ns;
-        this.name = name;
-        this.description = description;
+               rdd = new RoleDAO.Data();
+        rdd.ns = ns;
+        rdd.name = name;
+        rdd.description = description;
+        rdd.perms = perms;
         this.full = null;
         this.encode = null;
-        this.perms = perms;
     }
     
     public String encode() {
         if (encode==null) {
-            encode = ns + '|' + name;
+            encode = rdd.ns + '|' + rdd.name;
         } 
         return encode;
     }
 
     public String fullName() {
         if (full==null) {
-            full = ns + '.' + name;
+            full = rdd.ns + '.' + rdd.name;
         } 
         return full;
     }
@@ -111,7 +113,7 @@ public class Role implements Comparable<Role> {
                     row = iter.next();
                     Role rk =new Role(row.getString(0),row.getString(1), row.getString(2),row.getSet(3,String.class));
                     keys.put(rk.encode(), rk);
-                    data.put(rk,rk.perms);
+                    data.put(rk,rk.rdd.perms);
                     byName.put(rk.fullName(), rk);
                 }
             } finally {
index bea3b5e..0b6eb7b 100644 (file)
@@ -312,7 +312,17 @@ public class UserRole implements Cloneable, CacheChange.Data  {
        csvw.row("ur",user(),ns(),rname(),Chrono.dateOnlyStamp(expires()),expires().getTime());
     }
     
-    public static void batchDelete(StringBuilder sb, List<String> row) {
+    public static Data row(List<String> row) {
+               Data data = new Data();
+               data.user = row.get(1);
+               data.ns = row.get(2);
+               data.rname = row.get(3);
+               data.role = data.ns + '.' + data.rname;
+               data.expires = new Date(Long.parseLong(row.get(5)));
+               return data;
+       }
+
+       public static void batchDelete(StringBuilder sb, List<String> row) {
        sb.append("DELETE from authz.user_role WHERE user='");
        sb.append(row.get(1));
        sb.append("' AND role='");
index 11eacd4..979bcd5 100644 (file)
@@ -36,15 +36,17 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
+import java.util.UUID;
 
 import org.onap.aaf.auth.batch.Batch;
+import org.onap.aaf.auth.batch.helpers.Approval;
 import org.onap.aaf.auth.batch.helpers.Cred;
+import org.onap.aaf.auth.batch.helpers.Cred.Instance;
 import org.onap.aaf.auth.batch.helpers.ExpireRange;
+import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
+import org.onap.aaf.auth.batch.helpers.Future;
 import org.onap.aaf.auth.batch.helpers.UserRole;
-import org.onap.aaf.auth.batch.helpers.Visitor;
 import org.onap.aaf.auth.batch.helpers.X509;
-import org.onap.aaf.auth.batch.helpers.Cred.Instance;
-import org.onap.aaf.auth.batch.helpers.ExpireRange.Range;
 import org.onap.aaf.auth.dao.cass.CredDAO;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.org.OrganizationException;
@@ -65,6 +67,7 @@ public class Expiring extends Batch {
        private Map<String, CSV.Writer> writerList;
        private ExpireRange expireRange;
        private Date deleteDate;
+       private CSV.Writer deleteCW;
        
        public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
         super(trans.env());
@@ -93,18 +96,19 @@ public class Expiring extends Batch {
                for(Range r : lr ) {
                        if(writerList.get(r.name())==null) {
                        File file = new File(logDir(),r.name() + sdate +CSV);
-                       CSV csv = new CSV(file);
+                       CSV csv = new CSV(env.access(),file);
                        CSV.Writer cw = csv.writer(false);
                        cw.row(INFO,r.name(),Chrono.dateOnlyStamp(expireRange.now),r.reportingLevel());
                        writerList.put(r.name(),cw);
                        if("Delete".equals(r.name())) {
                                deleteDate = r.getEnd();
+                               deleteCW = cw;
                        }
                        trans.init().log("Creating File:",file.getAbsolutePath());
                        }
                }
             }
-            
+            Approval.load(trans, session, Approval.v2_0_17);
         } finally {
             tt0.done();
         }
@@ -112,12 +116,33 @@ public class Expiring extends Batch {
 
     @Override
     protected void run(AuthzTrans trans) {
+       
+               ////////////////////
+               trans.info().log("Checking for Expired Futures");
+               Future.load(trans, session, Future.v2_0_17, fut -> {
+                       if(fut.expires().before(expireRange.now)) {
+                               Future.row(deleteCW,fut);
+                               List<Approval> appls = Approval.byTicket.get(fut.id());
+                               if(appls!=null) {
+                                       for(Approval a : appls) {
+                                               Approval.row(deleteCW, a);
+                                       }
+                               }
+                       }
+               });
+               
                try {
                        File file = new File(logDir(), EXPIRED_OWNERS + Chrono.dateOnlyStamp(expireRange.now) + CSV);
-                       final CSV ownerCSV = new CSV(file);
+                       final CSV ownerCSV = new CSV(env.access(),file);
 
                        Map<String, Set<UserRole>> owners = new TreeMap<String, Set<UserRole>>();
                        trans.info().log("Process UserRoles");
+                       
+                       /**
+                          Run through User Roles.  
+                          Owners are treated specially in next section.
+                          Regular roles are checked against Date Ranges.  If match Date Range, write out to appropriate file.
+                       */
                        UserRole.load(trans, session, UserRole.v2_0_11, ur -> {
                                // Cannot just delete owners, unless there is at least one left. Process later
                                if ("owner".equals(ur.rname())) {
@@ -132,11 +157,12 @@ public class Expiring extends Batch {
                                }
                        });
 
-                       // Now Process Owners, one owner Role at a time, ensuring one is left,
-                       // preferably
-                       // a good one. If so, process the others as normal. Otherwise, write
-                       // ExpiredOwners
-                       // report
+                       /**
+                         Now Process Owners, one owner Role at a time, ensuring one is left,
+                         preferably a good one. If so, process the others as normal. 
+                         
+                         Otherwise, write to ExpiredOwners Report
+                       */
                        if (!owners.values().isEmpty()) {
                                // Lazy Create file
                                CSV.Writer expOwner = null;
@@ -168,8 +194,12 @@ public class Expiring extends Batch {
                                }
                        }
                        
-                       trans.info().log("Checking for Expired Credentials");
-                       
+                       /**
+                        * Check for Expired Credentials
+                        * 
+                        * 
+                        */
+                       trans.info().log("Checking for Expired Credentials");                   
                        for (Cred cred : Cred.data.values()) {
                        List<Instance> linst = cred.instances;
                        if(linst!=null) {
@@ -191,7 +221,8 @@ public class Expiring extends Batch {
                                }
                        }
                        }
-                       
+
+                       ////////////////////
                        trans.info().log("Checking for Expired X509s");
                        X509.load(trans, session, x509 -> {
                                try {
@@ -203,9 +234,21 @@ public class Expiring extends Batch {
                                }
 
                        });
+
                } catch (FileNotFoundException e) {
                        trans.info().log(e);
                }
+               
+               ////////////////////
+               trans.info().log("Checking for Orphaned Approvals");
+               Approval.load(trans, session, Approval.v2_0_17, appr -> {
+                       UUID ticket = appr.add.ticket;
+                       if(ticket==null) {
+                               Approval.row(deleteCW,appr);
+                       }
+               });
+               
+
        }
     
  
index ab8b6e8..f47fae4 100644 (file)
@@ -79,7 +79,7 @@ public class NotInOrg extends Batch {
             now = new Date();
             String sdate = Chrono.dateOnlyStamp(now);
                File file = new File(logDir(),NOT_IN_ORG + sdate +CSV);
-            CSV csv = new CSV(file);
+            CSV csv = new CSV(env.access(),file);
             notInOrgW = csv.writer(false);
             notInOrgW.row(INFO,NOT_IN_ORG,Chrono.dateOnlyStamp(now),0);
             writerList.put(NOT_IN_ORG,notInOrgW);
@@ -87,7 +87,7 @@ public class NotInOrg extends Batch {
             // These will have been double-checked by the Organization, and can be deleted immediately.
             String fn = NOT_IN_ORG+"Delete";
             file = new File(logDir(),fn + sdate +CSV);
-            CSV csvDelete = new CSV(file);
+            CSV csvDelete = new CSV(env.access(),file);
             notInOrgDeleteW = csvDelete.writer(false);
             notInOrgDeleteW.row(INFO,fn,Chrono.dateOnlyStamp(now),0);
             writerList.put(NOT_IN_ORG,notInOrgW);
index 547b657..f8d9888 100644 (file)
@@ -120,7 +120,7 @@ public class Notify extends Batch {
                
                try {
                        for(File f : notifyFile) {
-                               CSV csv = new CSV(f);
+                               CSV csv = new CSV(env.access(),f);
                                try {
                                        csv.visit(new CSV.Visitor() {
                                                @Override
index 1a7d774..fcdc663 100644 (file)
@@ -68,7 +68,7 @@ public class NsRoleUserReport extends Batch {
             now = new Date();
             String sdate = Chrono.dateOnlyStamp(now);
                File file = new File(logDir(),REPORT + sdate +CSV);
-            CSV csv = new CSV(file);
+            CSV csv = new CSV(env.access(),file);
             report = csv.writer(false);
             
             theMap = new TreeMap<>();
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
new file mode 100644 (file)
index 0000000..341a072
--- /dev/null
@@ -0,0 +1,207 @@
+/**
+ * ============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.update;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.onap.aaf.auth.batch.Batch;
+import org.onap.aaf.auth.batch.BatchPrincipal;
+import org.onap.aaf.auth.batch.approvalsets.ApprovalSet;
+import org.onap.aaf.auth.batch.approvalsets.URApprovalSet;
+import org.onap.aaf.auth.batch.helpers.Approval;
+import org.onap.aaf.auth.batch.helpers.BatchDataView;
+import org.onap.aaf.auth.batch.helpers.Future;
+import org.onap.aaf.auth.batch.helpers.NS;
+import org.onap.aaf.auth.batch.helpers.Role;
+import org.onap.aaf.auth.batch.helpers.UserRole;
+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.CadiException;
+import org.onap.aaf.cadi.util.CSV;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class Approvals extends Batch {
+    private final AuthzTrans noAvg;
+       private BatchDataView dataview;
+
+    public Approvals(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+        super(trans.env());
+        
+        noAvg = env.newTransNoAvg();
+        noAvg.setUser(new BatchPrincipal("batch:Approvals"));
+
+        dataview = new BatchDataView(noAvg,cluster,dryRun);
+        
+        session = dataview.getSession(trans);
+        
+        Approval.load(trans, session, Approval.v2_0_17);
+        Future.load(trans, session, Future.v2_0_17);
+        Role.load(trans, session);
+        NS.load(trans, session, NS.v2_0_11);
+        UserRole.load(trans, session, UserRole.v2_0_11);
+    }
+
+    @Override
+    protected void run(AuthzTrans trans) {
+        // Create Intermediate Output 
+        final GregorianCalendar now = new GregorianCalendar();
+        
+        List<File> approveFiles = new ArrayList<>();
+        if(args().length>0) {
+               for(int i=0;i<args().length;++i) {
+                       approveFiles.add(new File(logDir(), args()[i]));
+               }
+        } else {
+               approveFiles.add(new File(logDir(),"OneMonth"+Chrono.dateOnlyStamp()+".csv"));
+        }
+        
+        for(File f : approveFiles) {
+               trans.init().log("Processing File:",f.getAbsolutePath());
+        }
+        
+//        GregorianCalendar gc = new GregorianCalendar();
+//        Date now = gc.getTime();
+//        String today = Chrono.dateOnlyStamp(now);
+        for(File f : approveFiles) {
+               trans.info().log("Processing ",f.getAbsolutePath(),"for Approvals");
+               if(f.exists()) {
+                       CSV approveCSV = new CSV(env.access(),f).processAll();
+                       try {
+                                       approveCSV.visit(row -> {
+                                               switch(row.get(0)) {
+                                                       case "ur":
+                                                               UserRoleDAO.Data urdd = UserRole.row(row);
+                                                               List<Approval> apvs = Approval.byUser.get(urdd.user);
+                                                               
+                                                               System.out.println(row);
+                                                               if(apvs==null) {
+                                                                       // Create an Approval
+                                                                       ApprovalSet uras = new URApprovalSet(noAvg, now, dataview, () -> {
+                                                                               return urdd;
+                                                                       });
+                                                                       Result<Void> rw = uras.write(noAvg);
+                                                                       if(rw.notOK()) {
+                                                                               System.out.println(rw.errorString());
+                                                                       }
+                                                               } else {
+                                                                       // Check that Existing Approval is still valid
+                                                                       for(Approval a : apvs) {
+                                                                               Future ticket = Future.data.get(a.add.ticket);
+                                                                               if(ticket==null) {
+                                                                                       // Orphaned Approval - delete
+                                                                               } else {
+                                                                                       
+                                                                               }
+                                                                       }
+                                                               }
+                                                               break;
+                                                       default:
+                                                               System.out.println(row);
+                                                               //noAvg.debug().printf("Ignoring %s",type);
+                                               }
+                                       });
+                               } catch (IOException | CadiException e) {
+                                       e.printStackTrace();
+                                       // .... but continue with next row
+                               }
+                       
+                       /*
+        List<Approval> pending = new ArrayList<>();
+        boolean isOwner,isSupervisor;
+        for (Entry<String, List<Approval>> es : Approval.byApprover.entrySet()) {
+            isOwner = isSupervisor = false;
+            String approver = es.getKey();
+            if (approver.indexOf('@')<0) {
+                approver += org.getRealm();
+            }
+            Date latestNotify=null, soonestExpire=null;
+            GregorianCalendar latest=new GregorianCalendar();
+            GregorianCalendar soonest=new GregorianCalendar();
+            pending.clear();
+            
+            for (Approval app : es.getValue()) {
+                Future f = app.getTicket()==null?null:Future.data.get(app.getTicket());
+                if (f==null) { // only Ticketed Approvals are valid.. the others are records.
+                    // Approvals without Tickets are no longer valid. 
+                    if ("pending".equals(app.getStatus())) {
+                        app.setStatus("lapsed");
+                        app.update(noAvg,apprDAO,dryRun); // obeys dryRun
+                    }
+                } else {
+                    if ((soonestExpire==null && f.expires()!=null) || (soonestExpire!=null && f.expires()!=null && soonestExpire.before(f.expires()))) {
+                        soonestExpire=f.expires();
+                    }
+
+                    if ("pending".equals(app.getStatus())) {
+                        if (!isOwner) {
+                            isOwner = "owner".equals(app.getType());
+                        }
+                        if (!isSupervisor) {
+                            isSupervisor = "supervisor".equals(app.getType());
+                        }
+
+                        if ((latestNotify==null && app.getLast_notified()!=null) ||(latestNotify!=null && app.getLast_notified()!=null && latestNotify.before(app.getLast_notified()))) {
+                            latestNotify=app.getLast_notified();
+                        }
+                        pending.add(app);
+                    }
+                }
+            }
+
+            if (!pending.isEmpty()) {
+                boolean go = false;
+                if (latestNotify==null) { // never notified... make it so
+                    go=true;
+                } else {
+                    if (!today.equals(Chrono.dateOnlyStamp(latest))) { // already notified today
+                        latest.setTime(latestNotify);
+                        soonest.setTime(soonestExpire);
+                        int year;
+                        int days = soonest.get(GregorianCalendar.DAY_OF_YEAR)-latest.get(GregorianCalendar.DAY_OF_YEAR);
+                        days+=((year=soonest.get(GregorianCalendar.YEAR))-latest.get(GregorianCalendar.YEAR))*365 + 
+                                (soonest.isLeapYear(year)?1:0);
+                        if (days<7) { // If Expirations get within a Week (or expired), notify everytime.
+                            go = true;
+                        }
+                    }
+                }
+            }
+          */
+               }
+        }
+    }
+    
+    @Override
+    protected void _close(AuthzTrans trans) {
+       if(session!=null) {
+               session.close();
+               session = null;
+       }
+    }
+}
index 4288b2e..ab563fe 100644 (file)
@@ -70,7 +70,7 @@ public class NotifyCredExpiring extends Batch {
        private CSV csv;
        private CSVInfo csvInfo;
 
-    public NotifyCredExpiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+    public NotifyCredExpiring(AuthzTrans trans) throws APIException, IOException, OrganizationException, CadiException {
         super(trans.env());
         TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
         try {
@@ -106,7 +106,7 @@ public class NotifyCredExpiring extends Batch {
         } else {
                File f = new File(logDir(),args()[0]);
                System.out.println("Reading " + f.getCanonicalPath());
-               csv = new CSV(f);
+               csv = new CSV(env.access(),f);
         }
         
         if(args().length<2) {
@@ -118,11 +118,7 @@ public class NotifyCredExpiring extends Batch {
         }
         
         csvInfo = new CSVInfo(System.err);
-        try {
-                       csv.visit(csvInfo);
-               } catch (CadiException e) {
-                       throw new APIException(e);
-               }
+               csv.visit(csvInfo);
         
         Notification.load(trans, session, Notification.v2_0_18);
         
index f2425f4..bcc8591 100644 (file)
@@ -31,8 +31,10 @@ import java.util.List;
 
 import org.onap.aaf.auth.batch.Batch;
 import org.onap.aaf.auth.batch.BatchPrincipal;
+import org.onap.aaf.auth.batch.helpers.Approval;
 import org.onap.aaf.auth.batch.helpers.CQLBatch;
 import org.onap.aaf.auth.batch.helpers.Cred;
+import org.onap.aaf.auth.batch.helpers.Future;
 import org.onap.aaf.auth.batch.helpers.UserRole;
 import org.onap.aaf.auth.batch.helpers.X509;
 import org.onap.aaf.auth.dao.CassAccess;
@@ -116,7 +118,7 @@ public class Remove extends Batch {
                for(File f : remove) {
                        trans.info().log("Processing ",f.getAbsolutePath(),"for Deletions");
                        if(f.exists()) {
-                               CSV removeCSV = new CSV(f);
+                               CSV removeCSV = new CSV(env.access(),f);
                                        
                                try {
                                        final StringBuilder sb = cqlBatch.begin();
@@ -140,6 +142,7 @@ public class Remove extends Batch {
                                                                                        case "NotInOrgDelete":
                                                                                                memoFmt.set("Identity %s was removed from %s on %s");
                                                                                                break;
+
                                                                                }
                                                                                break;
                                                                        case "ur":
@@ -175,6 +178,16 @@ public class Remove extends Batch {
                                                                                hdd.memo=X509.histMemo(memoFmt.get(),row);
                                                                                historyDAO.createBatch(sb, hdd);
                                                                                break;
+                                                                       case "future":
+                                                                               // Not cached
+                                                                               hi.set(++i);
+                                                                               Future.deleteByIDBatch(sb,row.get(1));
+                                                                               break;
+                                                                       case "approval":
+                                                                               // Not cached
+                                                                               hi.set(++i);
+                                                                               Approval.deleteByIDBatch(sb,row.get(1));
+                                                                               break;
                                                                }
                                                        }
                                                });
index 96cbf28..10c0ec9 100644 (file)
@@ -29,7 +29,6 @@ import java.util.List;
 import java.util.UUID;
 
 import org.onap.aaf.auth.dao.CassDAOImpl;
-import org.onap.aaf.auth.dao.DAOException;
 import org.onap.aaf.auth.dao.Loader;
 import org.onap.aaf.auth.env.AuthzTrans;
 import org.onap.aaf.auth.layer.Result;
@@ -125,8 +124,6 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> {
                 obj[++idx]=data.target;
             }
         },readConsistency);
-        
-
     }
 
     public Result<List<Data>> readByStartAndTarget(AuthzTrans trans, Date start, String target) {
@@ -136,7 +133,7 @@ public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> {
     /**
      * Override create to add secondary ID to Subject in History, and create Data.ID, if it is null
      */
-    public Result<FutureDAO.Data> create(AuthzTrans trans,    FutureDAO.Data data, String id) {
+    public Result<FutureDAO.Data> create(AuthzTrans trans, FutureDAO.Data data, String id) {
         // If ID is not set (typical), create one.
         if (data.id==null) {
             StringBuilder sb = new StringBuilder(trans.user());
index 26f9a99..b6cbcf8 100644 (file)
@@ -140,8 +140,6 @@ public class UserRoleDAO extends CassDAOImpl<AuthzTrans,UserRoleDAO.Data> {
         public String toString() {
             return user + '|' + ns + '|' +  rname + '|' + Chrono.dateStamp(expires);
         }
-
-
     }
     
     private static class URLoader extends Loader<Data> implements Streamer<Data> {
index f440a8c..5a5fada 100644 (file)
@@ -136,11 +136,8 @@ public class Function {
                     sb = new StringBuilder();
                     ao = new ArrayList<>();
                 }
-                sb.append(result.details);
+                sb.append(String.format(result.details,result.variables));
                 sb.append('\n');
-                for (String s : result.variables) {
-                    ao.add(s);
-                }
             }
         }
 
index 4952dbe..2a49d3c 100644 (file)
@@ -53,7 +53,7 @@ public interface Facade<REQ,CERT,ARTIFACTS,ERROR> {
      * @param response
      * @param status
      */
-    void error(AuthzTrans trans, HttpServletResponse response, int status,    String msg, String ... detail);
+    void error(AuthzTrans trans, HttpServletResponse response, int status,    String msg, Object ... detail);
 
     /**
      * Permission checker
index 10e20ed..cba5379 100644 (file)
@@ -136,11 +136,11 @@ public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf.
     public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {
         error(trans, response, result.status,
                 result.details==null?"":result.details.trim(),
-                result.variables==null?new String[0]:result.variables);
+                result.variables==null?Result.EMPTY_VARS:result.variables);
     }
         
     @Override
-    public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final String ... _detail) {
+    public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final Object ... _detail) {
         String msgId;
         String prefix;
         boolean hidemsg=false;
index 7328f09..4a7019d 100644 (file)
@@ -40,7 +40,7 @@ public interface Mapper<REQ,CERT,ARTIFACTS,ERROR>
     public Class<?> getClass(API api);
     public<A> A newInstance(API api);
 
-    public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, String... detail);
+    public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, Object ... detail);
     
     public Result<CERT> toCert(AuthzTrans trans, Result<CertResp> in, boolean withTrustChain) throws IOException;
     public Result<CERT> toCert(AuthzTrans trans, Result<List<CertDAO.Data>> in);
index 99d0c47..663cee8 100644 (file)
@@ -81,13 +81,13 @@ public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> {
 
     //////////////  Mapping Functions /////////////
     @Override
-    public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
+    public Error errorFromMessage(StringBuilder holder, String msgID, String text, Object ... var) {
         Error err = new Error();
         err.setMessageId(msgID);
         // AT&T Restful Error Format requires numbers "%" placements
         err.setText(Vars.convert(holder, text, var));
-        for (String s : var) {
-            err.getVariables().add(s);
+        for (Object s : var) {
+            err.getVariables().add(s.toString());
         }
         return err;
     }
index 55a292e..3ff88d2 100644 (file)
@@ -81,13 +81,13 @@ public class Mapper2_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> {
 
     //////////////  Mapping Functions /////////////
     @Override
-    public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
+    public Error errorFromMessage(StringBuilder holder, String msgID, String text, Object ... var) {
         Error err = new Error();
         err.setMessageId(msgID);
         // AT&T Restful Error Format requires numbers "%" placements
         err.setText(Vars.convert(holder, text, var));
-        for (String s : var) {
-            err.getVariables().add(s);
+        for (Object s : var) {
+            err.getVariables().add(s.toString());
         }
         return err;
     }
index 8841eb2..ab3172f 100644 (file)
@@ -201,7 +201,7 @@ public class JU_AAF_CM {
                }
 
                @Override
-               protected TimeTaken newTimeTaken(String name, int flag) {
+               protected TimeTaken newTimeTaken(String name, int flag, Object ... values) {
                        // TODO Auto-generated method stub
                        TimeTaken tt= new TimeTaken("nameTest", Env.XML) {
                                
index d1c5d28..942a0e5 100644 (file)
@@ -93,10 +93,11 @@ public class NullTrans implements AuthzTrans {
         return LogTarget.NULL;
     }
 
-    public TimeTaken start(String name, int flag) {
-        return new TimeTaken(name,flag) {
+    @Override
+    public TimeTaken start(String name, int flag, Object ... values) {
+        return new TimeTaken(name,flag, values) {
             public void output(StringBuilder sb) {
-                sb.append(name);
+                sb.append(String.format(name,values));
                 sb.append(' ');
                 sb.append(millis());
                 sb.append("ms");
index e064ade..9d7347a 100644 (file)
@@ -34,7 +34,7 @@ import java.util.Set;
  */
 public class Result<RV> {
     private static final String SUCCESS = "Success";
-    public static final String[] EMPTY_VARS = new String[0];
+    public static final Object[] EMPTY_VARS = new Object[0];
 
     public final static int OK=0,
                             ERR_Security                 = 1,
@@ -51,9 +51,9 @@ public class Result<RV> {
     public RV value;
     public final int status;
     public final String details;
-    public final String[] variables;
+    public final Object[] variables;
     
-    public Result(RV value, int status, String details, String[] variables) {
+    public Result(RV value, int status, String details, Object ... variables) {
         this.value = value;
         if (value==null) {
         specialCondition|=EMPTY_LIST;
@@ -77,7 +77,7 @@ public class Result<RV> {
      * @return
      */
     public static<R> Result<R> ok(R value) {
-        return new Result<R>(value,OK,SUCCESS,null);
+        return new Result<R>(value,OK,SUCCESS,EMPTY_VARS);
     }
 
     /**
@@ -86,7 +86,7 @@ public class Result<RV> {
      * @return
      */
     public static<R> Result<R[]> ok(R value[]) {
-        return new Result<R[]>(value,OK,SUCCESS,null).emptyList(value.length==0);
+        return new Result<R[]>(value,OK,SUCCESS,EMPTY_VARS).emptyList(value.length==0);
     }
 
     /**
@@ -95,7 +95,7 @@ public class Result<RV> {
      * @return
      */
     public static<R> Result<Set<R>> ok(Set<R> value) {
-        return new Result<Set<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
+        return new Result<Set<R>>(value,OK,SUCCESS,EMPTY_VARS).emptyList(value.size()==0);
     }
 
     /**
@@ -104,7 +104,7 @@ public class Result<RV> {
      * @return
      */
     public static<R> Result<List<R>> ok(List<R> value) {
-        return new Result<List<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
+        return new Result<List<R>>(value,OK,SUCCESS,EMPTY_VARS).emptyList(value.size()==0);
     }
 
     /**
@@ -113,7 +113,7 @@ public class Result<RV> {
      * @return
      */
     public static<R> Result<Collection<R>> ok(Collection<R> value) {
-        return new Result<Collection<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);
+        return new Result<Collection<R>>(value,OK,SUCCESS,EMPTY_VARS).emptyList(value.size()==0);
     }
 
 
@@ -122,7 +122,7 @@ public class Result<RV> {
      * @return
      */
     public static Result<Void> ok() {
-        return new Result<Void>(null,OK,SUCCESS,null);
+        return new Result<Void>(null,OK,SUCCESS,EMPTY_VARS);
     }
 
     /**
@@ -143,7 +143,7 @@ public class Result<RV> {
      * @param variables
      * @return
      */
-    public static<R> Result<R> err(int status, String details, String ... variables) {
+    public static<R> Result<R> err(int status, String details, Object ... variables) {
         return new Result<R>(null,status,details,variables);
     }
 
@@ -172,7 +172,7 @@ public class Result<RV> {
      * @param details
      * @return
      */
-    public static<R> Result<R> create(R value, int status, String details, String ... vars) {
+    public static<R> Result<R> create(R value, int status, String details, Object ... vars) {
         return new Result<R>(value,status,details,vars);
     }
 
@@ -322,7 +322,7 @@ public class Result<RV> {
             default: sb.append("Error");
         }
         sb.append(" - ");
-        sb.append(String.format(details, (Object[])variables));
+        sb.append(String.format(details, variables));
         return sb.toString();
     }
 }
index c0bb8e7..23011d2 100644 (file)
@@ -50,7 +50,7 @@ public interface OAFacade<INTROSPECT> {
      * @param response
      * @param status
      */
-    public void error(AuthzTrans trans, HttpServletResponse response, int status,    String msg, String ... detail);
+    public void error(AuthzTrans trans, HttpServletResponse response, int status, String msg, Object ... detail);
 
     public Result<Void> createBearerToken(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);
 
index e5e12bd..6330664 100644 (file)
@@ -237,11 +237,11 @@ public abstract class OAFacadeImpl<TOKEN_REQ,TOKEN,INTROSPECT,ERROR>
     public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {
         error(trans, response, result.status,
                 result.details==null?"":result.details.trim(),
-                result.variables==null?new String[0]:result.variables);
+                result.variables==null?Result.EMPTY_VARS:result.variables);
     }
         
     @Override
-    public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final String ... _detail) {
+    public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final Object ... _detail) {
         String msgId;
         String prefix;
         boolean hidemsg=false;
index 8e1c52e..d741469 100644 (file)
@@ -37,7 +37,7 @@ public interface Mapper<TOKEN_REQ,TOKEN,INTROSPECT,ERROR> extends MapperIntrospe
     public Class<?> getClass(API api);
     public<A> A newInstance(API api);
 
-    public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, String... detail);
+    public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, Object ... detail);
     public TOKEN_REQ tokenReqFromParams(HttpServletRequest req);
     public OCreds credsFromReq(TOKEN_REQ tokReq);
     
index 027a51a..d4852c1 100644 (file)
@@ -73,13 +73,13 @@ public class Mapper1_0 extends MapperIntrospect1_0 implements Mapper<TokenReques
 
     //////////////  Mapping Functions /////////////
     @Override
-    public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {
+    public Error errorFromMessage(StringBuilder holder, String msgID, String text, Object ... var) {
         Error err = new Error();
         err.setMessageId(msgID);
         // AT&T Restful Error Format requires numbers "%" placements
         err.setText(Vars.convert(holder, text, var));
-        for (String s : var) {
-            err.getVariables().add(s);
+        for (Object s : var) {
+            err.getVariables().add(s.toString());
         }
         return err;
     }
index 1a016be..1cc8825 100644 (file)
@@ -280,7 +280,10 @@ public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DE
                 break;
             case ERR_ChoiceNeeded:
                 msgId = "SVC1300";
-                detail = result.variables;
+                detail = new String[result.variables.length];
+                for(int i=0; i<result.variables.length;++i) {
+                       detail[i]=result.variables.toString();
+                }
                 response.setStatus(/*httpstatus=*/300);
                 break;
             case ERR_Backend: 
index 1e4e9c0..93ab4ab 100644 (file)
@@ -25,7 +25,6 @@ import java.net.URISyntaxException;
 
 import org.onap.aaf.cadi.Locator;
 import org.onap.aaf.cadi.LocatorException;
-import org.onap.aaf.misc.env.impl.BasicTrans;
 
 /**
  * This Locator good for using Inside Docker or K8s, where there is no real lookup, 
index ea40440..99c3c3f 100644 (file)
@@ -92,7 +92,7 @@ public class AAFTaf<CLIENT> extends AbsUserCache<AAFPermission> implements HttpT
                mapIds=null;
         } else {
                try {
-                               mapIds = new MapBathConverter(access, new CSV(csvFile));
+                               mapIds = new MapBathConverter(access, new CSV(access,csvFile));
                                access.log(Level.INIT,"Basic Auth Conversion using",csvFile,"enabled" );
                        } catch (IOException | CadiException e) {
                                access.log(e,"Bath Map Conversion is not initialized (non fatal)");
index 3466a8d..d5c8846 100644 (file)
@@ -83,7 +83,7 @@ public class BasicHttpTaf implements HttpTaf {
                mapIds=null;
         } else {
                try {
-                               mapIds = new MapBathConverter(access, new CSV(csvFile));
+                               mapIds = new MapBathConverter(access, new CSV(access,csvFile));
                        } catch (IOException | CadiException e) {
                                access.log(e,"Bath Map Conversion is not initialzed (non fatal)");
                        }
index ed4fcde..a834db5 100644 (file)
@@ -30,7 +30,9 @@ import java.io.PrintStream;
 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;
 
 /**
  * Read CSV file for various purposes
@@ -40,17 +42,26 @@ import org.onap.aaf.cadi.CadiException;
  */
 public class CSV {
        private File csv;
+       private Access access;
+       private boolean processAll;
        
-       public CSV(File file) {
+       public CSV(Access access, File file) {
+               this.access = access;
                csv = file;
+               processAll = false;
        }
        
-       public CSV(String csvFilename) {
+       public CSV(Access access, String csvFilename) {
+               this.access = access;
                csv = new File(csvFilename);
+               processAll = false;
        }
        
-
-       /**
+       public CSV processAll() {
+               processAll = true;
+               return this;
+       }
+       /*
         * Create your code to accept the List<String> row.
         * 
         * Your code may keep the List... CSV does not hold onto it.
@@ -117,7 +128,15 @@ public class CSV {
                                                row.add(sb.toString());
                                                sb.setLength(0);
                                        }
-                                       visitor.visit(row);
+                                       try {
+                                               visitor.visit(row);
+                                       } catch (CadiException e) {
+                                               if(processAll) {
+                                                       access.log(Level.ERROR,e);
+                                               } else {
+                                                       throw e;
+                                               }
+                                       }
                                }
                        }
                } finally {
@@ -147,7 +166,8 @@ public class CSV {
                                        } else {
                                                ps.append(',');
                                        }
-                                       if(o instanceof String[]) {
+                                       if(o == null) {
+                                       } else if(o instanceof String[]) {
                                                for(String str : (String[])o) {
                                                        print(str);
                                                }
index 9751969..417351f 100644 (file)
@@ -31,8 +31,8 @@ public class Vars {
      * @return
      */
     public static String convert(final String text, final List<String> vars) {
-        String[] array = new String[vars.size()];
         StringBuilder sb = new StringBuilder();
+        Object[] array = new Object[vars.size()];
         convert(sb,text,vars.toArray(array));
         return sb.toString();
     }
@@ -44,7 +44,7 @@ public class Vars {
      * @param vars
      * @return
      */
-    public static String convert(final StringBuilder holder, final String text, final String ... vars) {
+    public static String convert(final StringBuilder holder, final String text, final Object ... vars) {
         StringBuilder sb = null;
         int idx,index=0,prev = 0;
         
index 9db542d..d9a5a0e 100644 (file)
@@ -62,7 +62,7 @@ public class JU_MapBathConverter {
        public static void createFile() throws IOException {
                // Note, you cate a "MapBathConverter" by access to a File.
                // We will create that file now.  Local is fine.
-               csv = new CSV("JU_MapBathConverter.csv"); 
+               csv = new CSV(access,"JU_MapBathConverter.csv"); 
        }
        
        @BeforeClass
@@ -109,7 +109,7 @@ public class JU_MapBathConverter {
                                                                break;
                                                        case 2:
                                                                try {
-                                                                       Date d = Date.valueOf(s);
+                                                                       Date.valueOf(s);
                                                                } catch (Exception e) {
                                                                        Assert.assertTrue("Last entry should be a date",false);
                                                                }
@@ -199,7 +199,7 @@ public class JU_MapBathConverter {
        @Test
        public void testNoFile() {
                try {
-                       new MapBathConverter(access, new CSV("Bogus"));
+                       new MapBathConverter(access, new CSV(access,"Bogus"));
                        Assert.fail("Non Existent File should throw exception");
                } catch(CadiException | IOException e) {
                        Assert.assertTrue("Correctly thrown Exception",true);
index f3e05d9..46fd741 100644 (file)
@@ -85,12 +85,6 @@ public class JU_RegistrationPropHolder {
                        String ns2 = "onap";
                        pa.setProperty(Config.AAF_LOCATOR_NS+".helm", ns2);
                        for(String dot_le : new String[] {"",".helm"}) {
-                               String pns;
-                               if(dot_le.isEmpty()) {
-                                       pns = ns;
-                               } else {
-                                       pns = ns2;
-                               }
                                assertEquals(rph.hostname,rph.default_fqdn);
                                assertEquals("",rph.lcontainer);
                                assertEquals(rph.hostname,rph.public_hostname);
index 54c48da..9df6de7 100644 (file)
@@ -34,7 +34,9 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.onap.aaf.cadi.Access;
 import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.PropAccess;
 import org.onap.aaf.cadi.util.CSV;
 import org.onap.aaf.cadi.util.CSV.Visitor;
 import org.onap.aaf.cadi.util.CSV.Writer;
@@ -65,7 +67,8 @@ public class JU_CSV {
        
        @Test
        public void test() throws IOException, CadiException {
-               CSV csv = new CSV(file);
+               Access access = new PropAccess();
+               CSV csv = new CSV(access,file);
                // Can't visit for file that doesn't exist
                try {
                        csv.visit(new Visitor() {
index f709a43..d6f4969 100644 (file)
@@ -115,7 +115,7 @@ public interface Env {
      * @param flag\r
      * @return\r
      */\r
-    public TimeTaken start(String name, int flag);\r
+    public TimeTaken start(String name, int flag, Object ... values);\r
     \r
     public String setProperty(String tag, String value);\r
     public String getProperty(String tag);\r
index 0201870..a1a81b9 100644 (file)
@@ -39,6 +39,7 @@ public abstract class TimeTaken {
     protected long end, size;\r
     public final int flag;\r
     public final String name;\r
+    public final Object[] values;\r
     \r
     /**\r
      * The name is as it will appear when written to output (abstract method)\r
@@ -47,11 +48,13 @@ public abstract class TimeTaken {
      * \r
      * @param name\r
      * @param flag\r
+     * @param values \r
      */\r
-    public TimeTaken(String name, int flag) {\r
+    public TimeTaken(String name, int flag, Object ... values) {\r
         start = System.nanoTime();\r
         this.flag = flag;\r
         this.name = name;\r
+        this.values = values;\r
         size = -1;\r
     }\r
 \r
index c0e7bde..83a049c 100644 (file)
@@ -92,22 +92,23 @@ public abstract class AbsTrans<ENV extends Env> implements TransStore {
      * @param flag\r
      * @return\r
      */\r
-    protected abstract TimeTaken newTimeTaken(String name, int flag);\r
+    protected abstract TimeTaken newTimeTaken(String name, int flag, Object ... values);\r
     \r
-//    @Override\r
-    public final TimeTaken start(String name, int flag) {\r
-        TimeTaken tt = newTimeTaken(name,flag);\r
+    @Override\r
+    public final TimeTaken start(String name, int flag, Object ... values) {\r
+        TimeTaken tt = newTimeTaken(name,flag, values);\r
         trail.add(tt);\r
         return tt;\r
     }\r
     \r
-//    @Override\r
+    @Override\r
     public final void checkpoint(String name) {\r
         TimeTaken tt = newTimeTaken(name,CHECKPOINT);\r
         tt.done();\r
         trail.add(tt);\r
     }\r
 \r
+    @Override\r
     public final void checkpoint(String name, int additionalFlag) {\r
         TimeTaken tt = newTimeTaken(name,CHECKPOINT|additionalFlag);\r
         trail.add(tt);\r
index 6fbfacd..35d0034 100644 (file)
@@ -149,9 +149,9 @@ public class BasicEnv extends StoreImpl implements EnvJAXB, TransCreate<TransJAX
         return trace;\r
     }\r
 \r
-    // @Override\r
-    public TimeTaken start(String name, int flag) {\r
-        return new TimeTaken(name, flag) {\r
+    @Override\r
+    public TimeTaken start(String name, int flag, Object ... values) {\r
+        return new TimeTaken(name, flag, values) {\r
             /**\r
              * Format to be printed when called upon\r
              */\r
@@ -163,7 +163,7 @@ public class BasicEnv extends StoreImpl implements EnvJAXB, TransCreate<TransJAX
                     case Env.JSON: sb.append("JSON "); break;\r
                     case Env.REMOTE: sb.append("REMOTE "); break;\r
                 }\r
-                sb.append(name);\r
+                sb.append(String.format(name, values));\r
                 if (flag != Env.CHECKPOINT) {\r
                     sb.append(' ');\r
                     sb.append((end-start)/1000000f);\r
index dbda57b..b9c3483 100644 (file)
@@ -36,11 +36,11 @@ public class BasicTrans extends AbsTransJAXB {
     }\r
 \r
     @Override\r
-    protected TimeTaken newTimeTaken(String name, int flag) {\r
+    protected TimeTaken newTimeTaken(String name, int flag, Object ... values) {\r
         /**\r
          * Note: could have created a different format for Time Taken, but using BasicEnv's instead\r
          */\r
-        return delegate.start(name, flag);\r
+        return delegate.start(name, flag, values);\r
     }\r
     \r
     public Slot slot(String name) {\r
index 572941f..9382160 100644 (file)
@@ -35,7 +35,6 @@ import org.onap.aaf.misc.env.Env;
 import org.onap.aaf.misc.env.LogTarget;
 import org.onap.aaf.misc.env.Slot;
 import org.onap.aaf.misc.env.StaticSlot;
-import org.onap.aaf.misc.env.StoreImpl;
 import org.onap.aaf.misc.env.TimeTaken;
 
 public class JU_AbsTrans {
@@ -109,7 +108,7 @@ public class JU_AbsTrans {
                }
 
                @Override
-               protected TimeTaken newTimeTaken(String name, int flag) {
+               protected TimeTaken newTimeTaken(String name, int flag, Object ... values) {
                        // TODO Auto-generated method stub
                        return new TimeTaken("nameTest", Env.XML) {
                                
index 9884880..22d979f 100644 (file)
@@ -103,7 +103,7 @@ public class JU_AbsTransJaxb {
                }
 
                @Override
-               protected TimeTaken newTimeTaken(String name, int flag) {
+               protected TimeTaken newTimeTaken(String name, int flag, Object ... values) {
                        // TODO Auto-generated method stub
                        return null;
                }