From ff1417ff60baee231a28272f9a16ef2c9c8ea0a2 Mon Sep 17 00:00:00 2001 From: Instrumental Date: Wed, 29 May 2019 04:58:50 -0500 Subject: [PATCH] Post Init Service Starter minor fixes Remove JU generated garbage files Issue-ID: AAF-835 Change-Id: I476291f1f1140f0640ed49452f8a5dabb28d9c30 Signed-off-by: Instrumental --- auth-client/src/main/xsd/aaf_2_0.xsd | 2 + .../org/onap/aaf/auth/batch/helpers/Creator.java | 14 +- .../main/java/org/onap/aaf/auth/dao/Cached.java | 2 +- .../org/onap/aaf/auth/dao/cass/CacheInfoDAO.java | 2 +- .../java/org/onap/aaf/auth/dao/cass/CredDAO.java | 2 +- .../org/onap/aaf/auth/dao/cass/HistoryDAO.java | 2 +- .../java/org/onap/aaf/auth/dao/cass/Status.java | 2 +- .../org/onap/aaf/auth/dao/hl/CassExecutor.java | 2 +- .../java/org/onap/aaf/auth/dao/hl/Function.java | 194 ++-- .../java/org/onap/aaf/auth/dao/hl/PermLookup.java | 6 +- .../java/org/onap/aaf/auth/dao/hl/Question.java | 97 +- .../test/java/org/onap/aaf/auth/dao/JU_Cached.java | 5 +- .../onap/aaf/auth/dao/cass/JU_CacheInfoDAO.java | 6 +- .../onap/aaf/auth/dao/cass/JU_ConfigDAOTest.java | 19 +- .../org/onap/aaf/auth/dao/cass/JU_LocateDAO.java | 14 +- .../java/org/onap/aaf/auth/dao/cass/JU_NsDAO.java | 13 +- .../onap/aaf/auth/dao/cass/JU_OAuthTokenDAO.java | 13 +- .../org/onap/aaf/auth/dao/cass/JU_PermDAO.java | 22 +- .../org/onap/aaf/auth/dao/cass/JU_RoleDAO.java | 14 +- .../org/onap/aaf/auth/dao/cass/JU_UserRoleDAO.java | 18 +- .../org/onap/aaf/auth/dao/hl/JU_CassExecutor.java | 14 +- .../java/org/onap/aaf/auth/dao/hl/JU_Function.java | 1127 +++++--------------- .../org/onap/aaf/auth/dao/hl/JU_PermLookup.java | 77 +- .../main/java/org/onap/aaf/auth/cm/ca/JscepCA.java | 4 +- .../org/onap/aaf/auth/cm/mapper/Mapper2_0.java | 51 +- .../aaf/auth/cm/validation/CertmanValidator.java | 3 + .../src/main/java/org/onap/aaf/auth/cmd/Cmd.java | 1 + .../java/org/onap/aaf/auth/cmd/perm/Grant.java | 104 +- .../main/java/org/onap/aaf/auth/cmd/role/User.java | 140 +-- .../main/java/org/onap/aaf/auth/cmd/user/List.java | 14 +- .../main/java/org/onap/aaf/auth/cmd/user/Role.java | 121 +-- .../org/onap/aaf/auth/cmd/test/perm/JU_Grant.java | 24 +- .../java/org/onap/aaf/auth/env/AuthzTrans.java | 2 + .../java/org/onap/aaf/auth/env/AuthzTransImpl.java | 28 +- .../main/java/org/onap/aaf/auth/env/NullTrans.java | 5 + .../org/onap/aaf/auth/rserv/CachingFileAccess.java | 8 +- .../java/org/onap/aaf/auth/rserv/RServlet.java | 12 + .../java/org/onap/aaf/auth/rserv/TransFilter.java | 3 +- .../onap/aaf/auth/server/AbsServiceStarter.java | 7 +- .../onap/aaf/auth/server/JettyServiceStarter.java | 3 +- .../java/org/onap/aaf/auth/server/Log4JLogIt.java | 22 +- .../src/main/java/org/onap/aaf/auth/fs/AAF_FS.java | 3 +- .../src/main/java/org/onap/aaf/auth/cui/CUI.java | 8 +- .../main/java/org/onap/aaf/auth/gui/AAF_GUI.java | 15 +- .../java/org/onap/aaf/auth/gui/BreadCrumbs.java | 2 +- .../main/java/org/onap/aaf/auth/gui/Display.java | 1 - .../src/main/java/org/onap/aaf/auth/gui/Page.java | 176 ++- .../java/org/onap/aaf/auth/gui/pages/Home.java | 42 +- .../org/onap/aaf/auth/gui/pages/WebCommand.java | 26 +- auth/auth-gui/theme/onap/images/AAF_details.png | Bin 0 -> 650 bytes auth/auth-gui/theme/onap/images/AAF_font_size.png | Bin 0 -> 1280 bytes auth/auth-gui/theme/onap/images/AAF_maximize.png | Bin 0 -> 593 bytes auth/auth-gui/theme/onap/images/AAFdownload.png | Bin 0 -> 1834 bytes auth/auth-gui/theme/onap/images/AAFemail.png | Bin 0 -> 2277 bytes .../theme/onap/images/LF_Collab_footer_gray.png | Bin 0 -> 47307 bytes .../onap/images/LF_Collab_footer_gray_stripe.png | Bin 0 -> 1374 bytes .../theme/onap/images/LF_Collab_header_gray.png | Bin 0 -> 21018 bytes auth/auth-gui/theme/onap/images/ONAP_LOGO.png | Bin 0 -> 24268 bytes auth/auth-gui/theme/onap/images/logo_onap.png | Bin 0 -> 11349 bytes .../onap/aaf/auth/locate/mapper/Mapper_1_1.java | 2 +- .../java/org/onap/aaf/auth/oauth/AAF_OAuth.java | 4 +- .../onap/aaf/auth/oauth/service/OAuthService.java | 2 +- .../org/onap/aaf/auth/service/AAF_Service.java | 17 +- .../aaf/auth/service/AuthzCassServiceImpl.java | 384 ++----- .../org/onap/aaf/auth/service/AuthzService.java | 17 +- .../org/onap/aaf/auth/service/api/API_Creds.java | 1 - .../onap/aaf/auth/service/api/API_UserRole.java | 28 +- .../onap/aaf/auth/service/facade/AuthzFacade.java | 6 +- .../aaf/auth/service/facade/AuthzFacadeImpl.java | 75 +- .../onap/aaf/auth/service/mapper/Mapper_2_0.java | 1 + auth/helm/aaf-hello/Chart.yaml | 2 +- auth/helm/aaf-hello/values.yaml | 2 +- auth/helm/aaf/Chart.yaml | 2 +- .../java/org/onap/aaf/cadi/register/Registrar.java | 1 + .../aaf/cadi/register/RegistrationCreator.java | 26 +- .../main/java/org/onap/aaf/cadi/sso/AAFSSO.java | 2 +- .../main/java/org/onap/aaf/cadi/PropAccess.java | 49 +- .../main/java/org/onap/aaf/cadi/config/Config.java | 8 + .../main/java/org/onap/aaf/misc/env/TimeTaken.java | 4 +- .../java/org/onap/aaf/misc/env/impl/AbsTrans.java | 25 +- .../java/org/onap/aaf/misc/env/impl/BasicEnv.java | 2 +- .../aaf/misc/env/impl/JU_Log4JLogTargetTest.java | 2 +- .../org/onap/aaf/misc/env/log4j/LogFileNamer.java | 25 +- .../aaf/misc/env/log4j/JU_LogFileNamerTest.java | 92 +- .../java/org/onap/aaf/misc/xgen/html/Imports.java | 1 - 85 files changed, 1360 insertions(+), 1912 deletions(-) create mode 100644 auth/auth-gui/theme/onap/images/AAF_details.png create mode 100644 auth/auth-gui/theme/onap/images/AAF_font_size.png create mode 100644 auth/auth-gui/theme/onap/images/AAF_maximize.png create mode 100644 auth/auth-gui/theme/onap/images/AAFdownload.png create mode 100644 auth/auth-gui/theme/onap/images/AAFemail.png create mode 100644 auth/auth-gui/theme/onap/images/LF_Collab_footer_gray.png create mode 100644 auth/auth-gui/theme/onap/images/LF_Collab_footer_gray_stripe.png create mode 100644 auth/auth-gui/theme/onap/images/LF_Collab_header_gray.png create mode 100644 auth/auth-gui/theme/onap/images/ONAP_LOGO.png create mode 100644 auth/auth-gui/theme/onap/images/logo_onap.png diff --git a/auth-client/src/main/xsd/aaf_2_0.xsd b/auth-client/src/main/xsd/aaf_2_0.xsd index b4b1ba9c..0cf39f1d 100644 --- a/auth-client/src/main/xsd/aaf_2_0.xsd +++ b/auth-client/src/main/xsd/aaf_2_0.xsd @@ -355,6 +355,8 @@ Type is not returned for "UserRole", but only "Cred" --> + + diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Creator.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Creator.java index 152c6331..9d0cfa7f 100644 --- a/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Creator.java +++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/batch/helpers/Creator.java @@ -27,11 +27,23 @@ public abstract class Creator { public abstract T create(Row row); public abstract String select(); + public String suffix() { + return ""; + } + public String query(String where) { StringBuilder sb = new StringBuilder(select()); if (where!=null) { sb.append(" WHERE "); - sb.append(where); + int index = where.indexOf(" ALLOW FILTERING"); + if(index< 0 ) { + sb.append(where); + sb.append(suffix()); + } else { + sb.append(where.substring(0, index)); + sb.append(suffix()); + sb.append(" ALLOW FILTERING"); + } } sb.append(';'); return sb.toString(); diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/Cached.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/Cached.java index 1bda405c..1888b3ac 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/Cached.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/Cached.java @@ -118,7 +118,7 @@ public class Cached extends Cache)cached.data; rld = Result.ok(ld); } else { diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CacheInfoDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CacheInfoDAO.java index 4aa94866..8cb25ac7 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CacheInfoDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CacheInfoDAO.java @@ -137,7 +137,7 @@ public class CacheInfoDAO extends CassDAOImpl impl } } - public static void startUpdate(AuthzEnv env, HMangr hman, SecuritySetter ss, String ip, int port) { + public static synchronized void startUpdate(AuthzEnv env, HMangr hman, SecuritySetter ss, String ip, int port) { if (cacheUpdate==null) { Thread t= new Thread(cacheUpdate = new CacheUpdate(env,hman,ss, ip,port),"CacheInfo Update Thread"); t.setDaemon(true); diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java index 01cc9237..9c57d200 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/CredDAO.java @@ -112,7 +112,7 @@ public class CredDAO extends CassDAOImpl { } } - private static class CredLoader extends Loader implements Streamer{ + public static class CredLoader extends Loader implements Streamer{ public static final int MAGIC=153323443; public static final int VERSION=2; public static final int BUFF_SIZE=48; // Note: diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java index 69d1d26e..73ab343b 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/HistoryDAO.java @@ -85,7 +85,7 @@ public class HistoryDAO extends CassDAOImpl { public ByteBuffer reconstruct; } - private static class HistLoader extends Loader { + public static class HistLoader extends Loader { public HistLoader(int keylimit) { super(keylimit); } diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/Status.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/Status.java index 8a617b94..a4d0bf4d 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/Status.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/cass/Status.java @@ -58,7 +58,7 @@ public class Status extends Result { * @param status */ private Status(RV value, int status, String details, String[] variables ) { - super(value,status,details,variables); + super(value,status,details,(Object[])variables); } public static String name(int status) { diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/CassExecutor.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/CassExecutor.java index 0bc23c92..a92de21c 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/CassExecutor.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/CassExecutor.java @@ -48,7 +48,7 @@ public class CassExecutor implements Executor { public boolean inRole(String name) { Result nss = q.deriveNsSplit(trans, name); if (nss.notOK())return false; - return q.roleDAO.read(trans, nss.value.ns,nss.value.name).isOKhasData(); + return q.roleDAO().read(trans, nss.value.ns,nss.value.name).isOKhasData(); } public boolean isGranted(String user, String ns, String type, String instance, String action) { diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java index 51bf594a..690ffa08 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Function.java @@ -227,6 +227,7 @@ public class Function { if (rparent.notOK()) { return Result.err(rparent); } + parent = rparent.value.parent; if (!fromApproval) { rparent = q.mayUser(trans, user, rparent.value, Access.write); if (rparent.notOK()) { @@ -234,12 +235,25 @@ public class Function { } } parent = namespace.parent = rparent.value.name; // Correct Namespace from real data + String cname = parent.length()<1 || namespace.name.equals(parent)?null:namespace.name.substring(parent.length()+1); // 2) Does requested NS exist - if (q.nsDAO.read(trans, namespace.name).isOKhasData()) { + if (q.nsDAO().read(trans, namespace.name).isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "Target Namespace already exists"); } + + // 2.1) Does role exist with that name + if(cname!=null && q.roleDAO().read(trans, parent, cname).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Role exists with that name"); + } + + // 2.2) Do perms exist with that name + if(cname!=null && q.permDAO().readByType(trans, parent, cname).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Perms exist with that name"); + } // Someone must be responsible. if (namespace.owner == null || namespace.owner.isEmpty()) { @@ -283,7 +297,7 @@ public class Function { } // VALIDATIONS done... Add NS - if ((rq = q.nsDAO.create(trans, namespace.data())).notOK()) { + if ((rq = q.nsDAO().create(trans, namespace.data())).notOK()) { return Result.err(rq); } @@ -296,12 +310,12 @@ public class Function { urdd.role(namespace.name, Question.ADMIN); for (String admin : namespace.admin) { urdd.user = admin; - eb.log(q.userRoleDAO.create(trans, urdd)); + eb.log(q.userRoleDAO().create(trans, urdd)); } urdd.role(namespace.name,Question.OWNER); for (String owner : namespace.owner) { urdd.user = owner; - eb.log(q.userRoleDAO.create(trans, urdd)); + eb.log(q.userRoleDAO().create(trans, urdd)); } addNSAdminRolesPerms(trans, eb, namespace.name); @@ -318,7 +332,7 @@ public class Function { int targetNameDot = targetName.length() + 1; // 4) Change any roles with children matching this NS, and - Result> rrdc = q.roleDAO.readChildren(trans, targetNs, targetName); + Result> rrdc = q.roleDAO().readChildren(trans, targetNs, targetName); if (rrdc.isOKhasData()) { for (RoleDAO.Data rdd : rrdc.value) { // Remove old Role from Perms, save them off @@ -328,7 +342,7 @@ public class Function { if (rpdd.isOKhasData()) { PermDAO.Data pdd = rpdd.value; lpdd.add(pdd); - q.permDAO.delRole(trans, pdd, rdd); + q.permDAO().delRole(trans, pdd, rdd); } else{ trans.error().log(rpdd.errorString()); } @@ -345,24 +359,24 @@ public class Function { // Need to use non-cached, because switching namespaces, not // "create" per se - if ((rq = q.roleDAO.create(trans, rdd)).isOK()) { + if ((rq = q.roleDAO().create(trans, rdd)).isOK()) { // Put Role back into Perm, with correct info for (PermDAO.Data pdd : lpdd) { - q.permDAO.addRole(trans, pdd, rdd); + q.permDAO().addRole(trans, pdd, rdd); } // Change data for User Roles - Result> rurd = q.userRoleDAO.readByRole(trans, rdd.fullName()); + Result> rurd = q.userRoleDAO().readByRole(trans, rdd.fullName()); if (rurd.isOKhasData()) { for (UserRoleDAO.Data urd : rurd.value) { urd.ns = rdd.ns; urd.rname = rdd.name; - q.userRoleDAO.update(trans, urd); + q.userRoleDAO().update(trans, urd); } } // Now delete old one rdd.ns = delP1; rdd.name = delP2; - if ((rq = q.roleDAO.delete(trans, rdd, false)).notOK()) { + if ((rq = q.roleDAO().delete(trans, rdd, false)).notOK()) { eb.log(rq); } } else { @@ -372,7 +386,7 @@ public class Function { } // 4) Change any Permissions with children matching this NS, and - Result> rpdc = q.permDAO.readChildren(trans,targetNs, targetName); + Result> rpdc = q.permDAO().readChildren(trans,targetNs, targetName); if (rpdc.isOKhasData()) { for (PermDAO.Data pdd : rpdc.value) { // Remove old Perm from Roles, save them off @@ -383,7 +397,7 @@ public class Function { if (rrdd.isOKhasData()) { RoleDAO.Data rdd = rrdd.value; lrdd.add(rdd); - q.roleDAO.delPerm(trans, rdd, pdd); + q.roleDAO().delPerm(trans, rdd, pdd); } else{ trans.error().log(rrdd.errorString()); } @@ -395,15 +409,15 @@ public class Function { pdd.ns = namespace.name; pdd.type = (delP2.length() > targetNameDot) ? delP2 .substring(targetNameDot) : ""; - if ((rq = q.permDAO.create(trans, pdd)).isOK()) { + if ((rq = q.permDAO().create(trans, pdd)).isOK()) { // Put Role back into Perm, with correct info for (RoleDAO.Data rdd : lrdd) { - q.roleDAO.addPerm(trans, rdd, pdd); + q.roleDAO().addPerm(trans, rdd, pdd); } pdd.ns = delP1; pdd.type = delP2; - if ((rq = q.permDAO.delete(trans, pdd, false)).notOK()) { + if ((rq = q.permDAO().delete(trans, pdd, false)).notOK()) { eb.log(rq); // Need to invalidate directly, because we're // switching places in NS, not normal cache behavior @@ -414,7 +428,7 @@ public class Function { } } if (eb.hasErr()) { - return Result.err(Status.ERR_ActionNotCompleted,eb.sb.toString(), eb.vars()); + return Result.err(Status.ERR_ActionNotCompleted,eb.sb.toString(), (Object[])eb.vars()); } } return Result.ok(); @@ -436,11 +450,11 @@ public class Function { rd.perms = new HashSet<>(); rd.perms.add(pd.encode()); - eb.log(q.roleDAO.create(trans, rd)); + eb.log(q.roleDAO().create(trans, rd)); pd.roles = new HashSet<>(); pd.roles.add(rd.encode()); - eb.log(q.permDAO.create(trans, pd)); + eb.log(q.permDAO().create(trans, pd)); } private void addNSOwnerRolesPerms(AuthzTrans trans, ErrBuilder eb, String ns) { @@ -458,11 +472,11 @@ public class Function { rd.perms = new HashSet<>(); rd.perms.add(pd.encode()); - eb.log(q.roleDAO.create(trans, rd)); + eb.log(q.roleDAO().create(trans, rd)); pd.roles = new HashSet<>(); pd.roles.add(rd.encode()); - eb.log(q.permDAO.create(trans, pd)); + eb.log(q.permDAO().create(trans, pd)); } /** @@ -491,7 +505,7 @@ public class Function { boolean move = trans.requested(REQD_TYPE.move); // 1) Validate Result> nsl; - if ((nsl = q.nsDAO.read(trans, ns)).notOKorIsEmpty()) { + if ((nsl = q.nsDAO().read(trans, ns)).notOKorIsEmpty()) { return Result.err(Status.ERR_NsNotFound, "%s does not exist", ns); } NsDAO.Data nsd = nsl.value.get(0); @@ -529,18 +543,18 @@ public class Function { ErrBuilder er = new ErrBuilder(); // 2a) Deny if any IDs on Namespace - Result> creds = q.credDAO.readNS(trans, ns); + Result> creds = q.credDAO().readNS(trans, ns); if (creds.isOKhasData()) { if (force || move) { for (CredDAO.Data cd : creds.value) { - er.log(q.credDAO.delete(trans, cd, false)); + er.log(q.credDAO().delete(trans, cd, false)); // Since we're deleting all the creds, we should delete all // the user Roles for that Cred - Result> rlurd = q.userRoleDAO + Result> rlurd = q.userRoleDAO() .readByUser(trans, cd.id); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { - q.userRoleDAO.delete(trans, data, false); + q.userRoleDAO().delete(trans, data, false); } } @@ -556,7 +570,7 @@ public class Function { // 2b) Find (or delete if forced flag is set) dependencies // First, find if NS Perms are the only ones - Result> rpdc = q.permDAO.readNS(trans, ns); + Result> rpdc = q.permDAO().readNS(trans, ns); if (rpdc.isOKhasData()) { // Since there are now NS perms, we have to count NON-NS perms. // FYI, if we delete them now, and the NS is not deleted, it is in @@ -581,7 +595,7 @@ public class Function { } } - Result> rrdc = q.roleDAO.readNS(trans, ns); + Result> rrdc = q.roleDAO().readNS(trans, ns); if (rrdc.isOKhasData()) { // Since there are now NS roles, we have to count NON-NS roles. // FYI, if we delete th)em now, and the NS is not deleted, it is in @@ -652,7 +666,7 @@ public class Function { } } - return q.nsDAO.delete(trans, nsd, false); + return q.nsDAO().delete(trans, nsd, false); } public Result> getOwners(AuthzTrans trans, String ns, @@ -712,7 +726,7 @@ public class Function { rq = q.mayUser(trans, trans.user(), rq.value, Access.write); if (rq.notOK()) { - Result> ruinr = q.userRoleDAO.readUserInRole(trans, trans.user(),ns+".owner"); + Result> ruinr = q.userRoleDAO().readUserInRole(trans, trans.user(),ns+".owner"); if (!(ruinr.isOKhasData() && ruinr.value.get(0).expires.after(new Date()))) { return Result.err(rq); } @@ -726,7 +740,7 @@ public class Function { try { if (org.getIdentity(trans, user) == null) { return Result.err(Status.ERR_Denied, - "%s reports that %s is a faulty ID", org.getName(), + "%s reports that %s is an invalid ID", org.getName(), user); } return Result.ok(); @@ -738,7 +752,7 @@ public class Function { // } else if (user.endsWith(ALTERNATE OAUTH DOMAIN)) { // return Result.ok(); } else { - Result> cdr = q.credDAO.readID(trans, user); + Result> cdr = q.credDAO().readID(trans, user); if (cdr.notOKorIsEmpty()) { return Result.err(Status.ERR_Security, "%s is not a valid AAF Credential", user); @@ -780,7 +794,7 @@ public class Function { rq = q.mayUser(trans, trans.user(), rq.value, Access.write); if (rq.notOK()) { // Even though not a "writer", Owners still determine who gets to be an Admin - Result> ruinr = q.userRoleDAO.readUserInRole(trans, trans.user(),ns+".owner"); + Result> ruinr = q.userRoleDAO().readUserInRole(trans, trans.user(),ns+".owner"); if (!(ruinr.isOKhasData() && ruinr.value.get(0).expires.after(new Date()))) { return Result.err(rq); } @@ -819,7 +833,7 @@ public class Function { if (rrdd.isOKhasData()) { RoleDAO.Data rdd = rrdd.value; lrdd.add(rdd); - q.roleDAO.delPerm(trans, rdd, pdd); + q.roleDAO().delPerm(trans, rdd, pdd); } else{ trans.error().log(rrdd.errorString()); } @@ -831,21 +845,21 @@ public class Function { pdd.ns = nss.ns; pdd.type = nss.name; // Use direct Create/Delete, because switching namespaces - if ((pd = q.permDAO.create(trans, pdd)).isOK()) { + if ((pd = q.permDAO().create(trans, pdd)).isOK()) { // Put Role back into Perm, with correct info for (RoleDAO.Data rdd : lrdd) { - q.roleDAO.addPerm(trans, rdd, pdd); + q.roleDAO().addPerm(trans, rdd, pdd); } pdd.ns = delP1; pdd.type = delP2; - if ((rv = q.permDAO.delete(trans, pdd, false)).notOK()) { + if ((rv = q.permDAO().delete(trans, pdd, false)).notOK()) { sb.append(rv.details); sb.append('\n'); // } else { // Need to invalidate directly, because we're switching // places in NS, not normal cache behavior - // q.permDAO.invalidate(trans,pdd); + // q.permDAO().invalidate(trans,pdd); } } else { sb.append(pd.details); @@ -884,7 +898,7 @@ public class Function { if (rpdd.isOKhasData()) { PermDAO.Data pdd = rpdd.value; lpdd.add(pdd); - q.permDAO.delRole(trans, pdd, rdd); + q.permDAO().delRole(trans, pdd, rdd); } else{ trans.error().log(rpdd.errorString()); } @@ -897,21 +911,21 @@ public class Function { rdd.ns = nss.ns; rdd.name = nss.name; // Use direct Create/Delete, because switching namespaces - if ((rd = q.roleDAO.create(trans, rdd)).isOK()) { + if ((rd = q.roleDAO().create(trans, rdd)).isOK()) { // Put Role back into Perm, with correct info for (PermDAO.Data pdd : lpdd) { - q.permDAO.addRole(trans, pdd, rdd); + q.permDAO().addRole(trans, pdd, rdd); } rdd.ns = delP1; rdd.name = delP2; - if ((rv = q.roleDAO.delete(trans, rdd, true)).notOK()) { + if ((rv = q.roleDAO().delete(trans, rdd, true)).notOK()) { sb.append(rv.details); sb.append('\n'); // } else { // Need to invalidate directly, because we're switching // places in NS, not normal cache behavior - // q.roleDAO.invalidate(trans,rdd); + // q.roleDAO().invalidate(trans,rdd); } } else { sb.append(rd.details); @@ -946,7 +960,7 @@ public class Function { // Does Child exist? if (!trans.requested(REQD_TYPE.force)) { - if (q.permDAO.read(trans, perm).isOKhasData()) { + if (q.permDAO().read(trans, perm).isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "Permission [%s.%s|%s|%s] already exists.", perm.ns, perm.type, perm.instance, perm.action); @@ -976,22 +990,22 @@ public class Function { } Result> rlrd; - if ((rlrd = q.roleDAO.read(trans, rd)).notOKorIsEmpty()) { + if ((rlrd = q.roleDAO().read(trans, rd)).notOKorIsEmpty()) { rd.perms(true).add(pstring); - if (q.roleDAO.create(trans, rd).notOK()) { + if (q.roleDAO().create(trans, rd).notOK()) { roles.remove(role); // Role doesn't exist, and can't be // created } } else { rd = rlrd.value.get(0); if (!rd.perms.contains(pstring)) { - q.roleDAO.addPerm(trans, rd, perm); + q.roleDAO().addPerm(trans, rd, perm); } } } } - Result pdr = q.permDAO.create(trans, perm); + Result pdr = q.permDAO().create(trans, perm); if (pdr.isOK()) { return Result.ok(); } else { @@ -1011,7 +1025,7 @@ public class Function { } } // Does Perm exist? - Result> pdr = q.permDAO.read(trans, perm); + Result> pdr = q.permDAO().read(trans, perm); if (pdr.notOKorIsEmpty()) { return Result.err(Status.ERR_PermissionNotFound,"Permission [%s.%s|%s|%s] does not exist.", perm.ns,perm.type, perm.instance, perm.action); @@ -1027,7 +1041,7 @@ public class Function { Result rrdd = RoleDAO.Data.decode(trans, q, role); if (rrdd.isOKhasData()) { trans.debug().log("Removing", role, "from", fullperm, "on Perm Delete"); - if ((rv = q.roleDAO.delPerm(trans, rrdd.value, fullperm)).notOK()) { + if ((rv = q.roleDAO().delPerm(trans, rrdd.value, fullperm)).notOK()) { if (rv.notOK()) { trans.error().log("Error removing Role during delFromPermRole: ", trans.getUserPrincipal(), @@ -1046,7 +1060,7 @@ public class Function { } } - return q.permDAO.delete(trans, fullperm, false); + return q.permDAO().delete(trans, fullperm, false); } public Result deleteRole(final AuthzTrans trans, final RoleDAO.Data role, boolean force, boolean fromApproval) { @@ -1062,11 +1076,11 @@ public class Function { } // Are there any Users Attached to Role? - Result> urdr = q.userRoleDAO.readByRole(trans,role.fullName()); + Result> urdr = q.userRoleDAO().readByRole(trans,role.fullName()); if (force) { if (urdr.isOKhasData()) { for (UserRoleDAO.Data urd : urdr.value) { - q.userRoleDAO.delete(trans, urd, false); + q.userRoleDAO().delete(trans, urd, false); } } } else if (urdr.isOKhasData()) { @@ -1076,7 +1090,7 @@ public class Function { } // Does Role exist? - Result> rdr = q.roleDAO.read(trans, role); + Result> rdr = q.roleDAO().read(trans, role); if (rdr.notOKorIsEmpty()) { return Result.err(Status.ERR_RoleNotFound, "Role [%s.%s] does not exist", role.ns, role.name); @@ -1090,7 +1104,7 @@ public class Function { if (rpd.isOK()) { trans.debug().log("Removing", perm, "from", fullrole,"on Role Delete"); - Result r = q.permDAO.delRole(trans, rpd.value, fullrole); + Result r = q.permDAO().delRole(trans, rpd.value, fullrole); if (r.notOK()) { trans.error().log("ERR_FDR1 unable to remove",fullrole,"from",perm,':',r.status,'-',r.details); } @@ -1099,7 +1113,7 @@ public class Function { } } } - return q.roleDAO.delete(trans, fullrole, false); + return q.roleDAO().delete(trans, fullrole, false); } /** @@ -1149,7 +1163,7 @@ public class Function { } // Final Check... Don't allow Grantees to add to Roles they are // part of - Result> rlurd = q.userRoleDAO + Result> rlurd = q.userRoleDAO() .readByUser(trans, trans.user()); if (rlurd.isOK()) { for (UserRoleDAO.Data ur : rlurd.value) { @@ -1161,13 +1175,13 @@ public class Function { } } - Result> rlpd = q.permDAO.read(trans, pd); + Result> rlpd = q.permDAO().read(trans, pd); if (rlpd.notOKorIsEmpty()) { return Result.err(Status.ERR_PermissionNotFound, "Permission must exist to add to Role"); } - Result> rlrd = q.roleDAO.read(trans, role); // Already + Result> rlrd = q.roleDAO().read(trans, role); // Already // Checked // for // can @@ -1187,7 +1201,7 @@ public class Function { } role.perms(true).add(pd.encode()); - Result rdd = q.roleDAO.create(trans, role); + Result rdd = q.roleDAO().create(trans, role); if (rdd.isOK()) { rv = Result.ok(); } else { @@ -1207,10 +1221,10 @@ public class Function { role.perms(true).add(pd.encode()); // this is added for Caching // access purposes... doesn't // affect addPerm - rv = q.roleDAO.addPerm(trans, role, pd); + rv = q.roleDAO().addPerm(trans, role, pd); } if (rv.status == Status.OK) { - return q.permDAO.addRole(trans, pd, role); + return q.permDAO().addRole(trans, pd, role); // exploring how to add information message to successful http // request } @@ -1241,13 +1255,13 @@ public class Function { } } - Result> rlr = q.roleDAO.read(trans, role); + Result> rlr = q.roleDAO().read(trans, role); if (rlr.notOKorIsEmpty()) { // If Bad Data, clean out - Result> rlp = q.permDAO.read(trans, pd); + Result> rlp = q.permDAO().read(trans, pd); if (rlp.isOKhasData()) { for (PermDAO.Data pv : rlp.value) { - q.permDAO.delRole(trans, pv, role); + q.permDAO().delRole(trans, pv, role); } } return Result.err(rlr); @@ -1279,12 +1293,12 @@ public class Function { } // Read Perm for full data - Result> rlp = q.permDAO.read(trans, pd); + Result> rlp = q.permDAO().read(trans, pd); Result rv = null; if (rlp.isOKhasData()) { for (PermDAO.Data pv : rlp.value) { - if ((rv = q.permDAO.delRole(trans, pv, role)).isOK()) { - if ((rv = q.roleDAO.delPerm(trans, role, pv)).notOK()) { + if ((rv = q.permDAO().delRole(trans, pv, role)).isOK()) { + if ((rv = q.roleDAO().delPerm(trans, role, pv)).notOK()) { trans.error().log( "Error removing Perm during delFromPermRole:", trans.getUserPrincipal(), rv.errorString()); @@ -1296,7 +1310,7 @@ public class Function { } } } else { - rv = q.roleDAO.delPerm(trans, role, pd); + rv = q.roleDAO().delPerm(trans, role, pd); if (rv.notOK()) { trans.error().log("Error removing Role during delFromPermRole", rv.errorString()); @@ -1342,11 +1356,11 @@ public class Function { } // Check if record exists - if (q.userRoleDAO.read(trans, urData).isOKhasData()) { + if (q.userRoleDAO().read(trans, urData).isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "User Role exists"); } - if (q.roleDAO.read(trans, urData.ns, urData.rname).notOKorIsEmpty()) { + if (q.roleDAO().read(trans, urData.ns, urData.rname).notOKorIsEmpty()) { return Result.err(Status.ERR_RoleNotFound, "Role [%s.%s] does not exist", urData.ns, urData.rname); } @@ -1354,7 +1368,7 @@ public class Function { urData.expires = trans.org().expiration(null, Expiration.UserInRole, urData.user).getTime(); - Result udr = q.userRoleDAO.create(trans, urData); + Result udr = q.userRoleDAO().create(trans, urData); if (udr.status == OK) { return Result.ok(); } @@ -1388,12 +1402,12 @@ public class Function { */ public Result extendUserRole(AuthzTrans trans, UserRoleDAO.Data urData, boolean checkForExist) { // Check if record still exists - if (checkForExist && q.userRoleDAO.read(trans, urData).notOKorIsEmpty()) { + if (checkForExist && q.userRoleDAO().read(trans, urData).notOKorIsEmpty()) { return Result.err(Status.ERR_UserRoleNotFound, "User Role does not exist"); } - if (q.roleDAO.read(trans, urData.ns, urData.rname).notOKorIsEmpty()) { + if (q.roleDAO().read(trans, urData.ns, urData.rname).notOKorIsEmpty()) { return Result.err(Status.ERR_RoleNotFound, "Role [%s.%s] does not exist", urData.ns,urData.rname); } @@ -1407,7 +1421,7 @@ public class Function { // time // starting // today - return q.userRoleDAO.update(trans, urData); + return q.userRoleDAO().update(trans, urData); } // //////////////////////////////////////////////////// @@ -1418,7 +1432,7 @@ public class Function { // Roles // //////////////////////////////////////////////////// public Result> getUsersByRole(AuthzTrans trans, String role, boolean includeExpired) { - Result> rurdd = q.userRoleDAO.readByRole(trans,role); + Result> rurdd = q.userRoleDAO().readByRole(trans,role); if (rurdd.notOK()) { return Result.err(rurdd); } @@ -1437,7 +1451,7 @@ public class Function { UserRoleDAO.Data urdd = new UserRoleDAO.Data(); urdd.user = user; urdd.role(ns,rname); - Result> r = q.userRoleDAO.read(trans, urdd); + Result> r = q.userRoleDAO().read(trans, urdd); if (r.status == 404 || r.isEmpty()) { return Result.err(Status.ERR_UserRoleNotFound, "UserRole [%s] [%s.%s]", user, ns, rname); @@ -1446,7 +1460,7 @@ public class Function { return Result.err(r); } - return q.userRoleDAO.delete(trans, urdd, false); + return q.userRoleDAO().delete(trans, urdd, false); } public Result createFuture(AuthzTrans trans, FutureDAO.Data data, String id, String user, @@ -1458,7 +1472,7 @@ public class Function { List approvers = op.equals(FUTURE_OP.A)?NO_ADDL_APPROVE:org.getApprovers(trans, user); List owners = new ArrayList<>(); if (nsd != null) { - Result> rrbr = q.userRoleDAO + Result> rrbr = q.userRoleDAO() .readByRole(trans, nsd.name + Question.DOT_OWNER); if (rrbr.isOKhasData()) { for (UserRoleDAO.Data urd : rrbr.value) { @@ -1478,7 +1492,7 @@ public class Function { // Create Future Object - Result fr = q.futureDAO.create(trans, data, id); + Result fr = q.futureDAO().create(trans, data, id); if (fr.isOK()) { sb.append("Created Future: "); sb.append(data.id); @@ -1518,7 +1532,7 @@ public class Function { public Lookup urDBLookup = new Lookup() { @Override public UserRoleDAO.Data get(AuthzTrans trans, Object ... keys) { - Result> r = q.userRoleDAO.read(trans, keys); + Result> r = q.userRoleDAO().read(trans, keys); if (r.isOKhasData()) { return r.value.get(0); } else { @@ -1549,11 +1563,11 @@ public class Function { // Get Current UserRole from lookup UserRoleDAO.Data lurdd = lur.get(trans, urdd.user,urdd.role); if (lurdd==null) { - q.futureDAO.delete(trans, curr, false); + q.futureDAO().delete(trans, curr, false); return OP_STATUS.RL; } else { if (curr.expires.compareTo(lurdd.expires)<0) { - q.futureDAO.delete(trans, curr, false); + q.futureDAO().delete(trans, curr, false); return OP_STATUS.RL; } } @@ -1593,7 +1607,7 @@ public class Function { Result ros=null; if (aDenial) { ros = OP_STATUS.RD; - if (q.futureDAO.delete(trans, curr, false).notOK()) { + if (q.futureDAO().delete(trans, curr, false).notOK()) { trans.info().printf("Future %s could not be deleted", curr.id.toString()); } else { if (FOP_USER_ROLE.equalsIgnoreCase(curr.target)) { @@ -1623,7 +1637,7 @@ public class Function { data.reconstitute(curr.construct); switch(fop) { case C: - ros = set(OP_STATUS.RE,q.roleDAO.dao().create(trans, data)); + ros = set(OP_STATUS.RE,q.roleDAO().dao().create(trans, data)); break; case D: ros = set(OP_STATUS.RE,deleteRole(trans, data, true, true)); @@ -1693,10 +1707,10 @@ public class Function { data.reconstitute(curr.construct); switch(fop) { case C: - ros = set(OP_STATUS.RE,q.delegateDAO.create(trans, data)); + ros = set(OP_STATUS.RE,q.delegateDAO().create(trans, data)); break; case U: - ros = set(OP_STATUS.RE,q.delegateDAO.update(trans, data)); + ros = set(OP_STATUS.RE,q.delegateDAO().update(trans, data)); break; default: } @@ -1704,7 +1718,7 @@ public class Function { CredDAO.Data data = new CredDAO.Data(); data.reconstitute(curr.construct); if (fop == FUTURE_OP.C) { - ros = set(OP_STATUS.RE, q.credDAO.dao().create(trans, data)); + ros = set(OP_STATUS.RE, q.credDAO().dao().create(trans, data)); } } } catch (Exception e) { @@ -1712,7 +1726,7 @@ public class Function { " \n occurred while performing", curr.memo, " from Ticket ", curr.id.toString()); } - q.futureDAO.delete(trans, curr, false); + q.futureDAO().delete(trans, curr, false); } // end for goDecision if (ros==null) { //return Result.err(Status.ACC_Future, "Full Approvals not obtained: No action taken"); @@ -1743,7 +1757,7 @@ public class Function { ad.type = type; ad.operation = op.name(); // Note ad.updated is created in System - Result r = q.approvalDAO.create(trans,ad); + Result r = q.approvalDAO().create(trans,ad); if (r.isOK()) { if (first[0]) { first[0] = false; diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/PermLookup.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/PermLookup.java index 98621457..8d15c958 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/PermLookup.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/PermLookup.java @@ -76,7 +76,7 @@ class PermLookup { public Result> getUserRoles() { if (userRoles==null) { - userRoles = q.userRoleDAO.readByUser(trans,user); + userRoles = q.userRoleDAO().readByUser(trans,user); if (userRoles.isOKhasData()) { List lurdd = new ArrayList<>(); Date now = new Date(); @@ -110,7 +110,7 @@ class PermLookup { if (urdata.ns==null || urdata.rname==null) { return Result.err(Status.ERR_BadData,"DB Content Error: nulls in User Role %s %s", urdata.user,urdata.role); } else { - Result> rlrd = q.roleDAO.read( + Result> rlrd = q.roleDAO().read( trans, urdata.ns, urdata.rname); if (rlrd.isOK()) { lrdd.addAll(rlrd.value); @@ -155,7 +155,7 @@ class PermLookup { Result ap = PermDAO.Data.decodeToArray(trans, q, perm); if (ap.isOK()) { - Result> rlpd = q.permDAO.read(perm,trans,ap.value); + Result> rlpd = q.permDAO().read(perm,trans,ap.value); if (rlpd.isOKhasData()) { for (PermDAO.Data pData : rlpd.value) { lpdd.add(pData); diff --git a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java index 7201958d..bd0c8355 100644 --- a/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java +++ b/auth/auth-cass/src/main/java/org/onap/aaf/auth/dao/hl/Question.java @@ -61,6 +61,7 @@ import org.onap.aaf.auth.dao.cass.PermDAO; import org.onap.aaf.auth.dao.cass.RoleDAO; import org.onap.aaf.auth.dao.cass.Status; import org.onap.aaf.auth.dao.cass.UserRoleDAO; +import org.onap.aaf.auth.env.AuthzEnv; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE; import org.onap.aaf.auth.env.AuthzTransFilter; @@ -129,20 +130,65 @@ public class Question { private static Slot transIDSlot = null; - public final HistoryDAO historyDAO; - public final CachedNSDAO nsDAO; - public CachedRoleDAO roleDAO; - public final CachedPermDAO permDAO; - public CachedUserRoleDAO userRoleDAO; - public final CachedCredDAO credDAO; - public final CachedCertDAO certDAO; - public final DelegateDAO delegateDAO; - public final FutureDAO futureDAO; - public final ApprovalDAO approvalDAO; - private final CacheInfoDAO cacheInfoDAO; + private final HistoryDAO historyDAO; + public HistoryDAO historyDAO() { + return historyDAO; + } + + private final CachedNSDAO nsDAO; + public CachedNSDAO nsDAO() { + return nsDAO; + } + + private final CachedRoleDAO roleDAO; + public CachedRoleDAO roleDAO() { + return roleDAO; + } + + private final CachedPermDAO permDAO; + public CachedPermDAO permDAO() { + return permDAO; + } + + private final CachedUserRoleDAO userRoleDAO; + public CachedUserRoleDAO userRoleDAO() { + return userRoleDAO; + } + + private final CachedCredDAO credDAO; + public CachedCredDAO credDAO() { + return credDAO; + } + + private final CachedCertDAO certDAO; + public CachedCertDAO certDAO() { + return certDAO; + } + + private final DelegateDAO delegateDAO; + public DelegateDAO delegateDAO() { + return delegateDAO; + } + + private final FutureDAO futureDAO; + public FutureDAO futureDAO() { + return futureDAO; + } + + private final ApprovalDAO approvalDAO; + public ApprovalDAO approvalDAO() { + return approvalDAO; + } + public final LocateDAO locateDAO; + public LocateDAO locateDAO() { + return locateDAO; + } + + private final CacheInfoDAO cacheInfoDAO; + private final int cldays; - public Question(AuthzTrans trans, Cluster cluster, String keyspace, boolean startClean) throws APIException, IOException { + public Question(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException { PERMS = trans.slot("USER_PERMS"); trans.init().log("Instantiating DAOs"); long expiresIn = Long.parseLong(trans.getProperty(Config.AAF_USER_EXPIRES, Config.AAF_USER_EXPIRES_DEF)); @@ -163,14 +209,6 @@ public class Question { delegateDAO = new DelegateDAO(trans, historyDAO); approvalDAO = new ApprovalDAO(trans, historyDAO); - // Only want to aggressively cleanse User related Caches... The others, - // just normal refresh - if (startClean) { - CachedDAO.startCleansing(trans.env(), credDAO, userRoleDAO); - CachedDAO.startRefresh(trans.env(), cacheInfoDAO); - } - // Set a Timer to Check Caches to send messages for Caching changes - if (specialLogSlot==null) { specialLogSlot = trans.slot(AuthzTransFilter.SPECIAL_LOG_SLOT); } @@ -180,9 +218,17 @@ public class Question { } AbsCassDAO.primePSIs(trans); + + cldays = Integer.parseInt(trans.getProperty(Config.AAF_CRED_WARN_DAYS, Config.AAF_CRED_WARN_DAYS_DFT)); } - + public void startTimers(AuthzEnv env) { + // Only want to aggressively cleanse User related Caches... The others, + // just normal refresh + CachedDAO.startCleansing(env, credDAO, userRoleDAO); + CachedDAO.startRefresh(env, cacheInfoDAO); + } + public void close(AuthzTrans trans) { historyDAO.close(trans); cacheInfoDAO.close(trans); @@ -784,7 +830,7 @@ public class Question { case CredDAO.BASIC_AUTH: byte[] md5=Hash.hashMD5(cred); if (Hash.compareTo(md5,dbcred)==0) { - checkLessThanDays(trans,7,now,cdd); + checkLessThanDays(trans,cldays,now,cdd); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -797,7 +843,7 @@ public class Question { byte[] hash = Hash.hashSHA256(bb.array()); if (Hash.compareTo(hash,dbcred)==0) { - checkLessThanDays(trans,7,now,cdd); + checkLessThanDays(trans,cldays,now,cdd); return Result.ok(cdd.expires); } else if (debug!=null) { load(debug, cdd); @@ -849,8 +895,9 @@ public class Question { long cexp=cdd.expires.getTime(); if (cexp retVal1 = new Result(null,1,"",new String[0]); + Result retVal1 = new Result(null,1,"",NO_PARAM); Mockito.doReturn(retVal1).when(q).deriveNsSplit(trans, "test"); boolean retVal = cassExecutorObj.inRole("test"); @@ -99,7 +101,7 @@ public class JU_CassExecutor { public void testNamespace() { f =new Function(trans, q); CassExecutor cassExecutorObj =new CassExecutor(trans, f); - Result retVal1 = new Result(null,1,"",new String[0]); + Result retVal1 = new Result(null,1,"",NO_PARAM); Mockito.doReturn(retVal1).when(q).validNSOfDomain(trans, null); String retVal=""; @@ -123,7 +125,7 @@ public class JU_CassExecutor { @Test public void testNamespaceSuccess() { - Mockito.doAnswer(new Answer() { + Mockito.doAnswer(new Answer() { private int count = 0; public Object answer(InvocationOnMock invocation) { @@ -135,13 +137,13 @@ public class JU_CassExecutor { }).when(trans).user(); f =new Function(trans, q); CassExecutor cassExecutorObj =new CassExecutor(trans, f); - Result retVal1 = new Result(null,0,"",new String[0]); + Result retVal1 = new Result(null,0,"",NO_PARAM); Mockito.doReturn(retVal1).when(q).validNSOfDomain(trans, null); - String retVal=""; +// String retVal=""; try { - retVal = cassExecutorObj.namespace(); + /*retVal =*/ cassExecutorObj.namespace(); } catch (Exception e) { e.printStackTrace(); System.out.println(e.getMessage()); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_Function.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_Function.java index 1f2727ce..ab7b2e59 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_Function.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_Function.java @@ -27,11 +27,8 @@ import static org.junit.Assert.assertTrue; import static org.mockito.MockitoAnnotations.initMocks; import java.io.IOException; -import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.nio.ByteBuffer; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -83,6 +80,8 @@ import org.onap.aaf.misc.env.LogTarget; public class JU_Function { + private static final Object NO_PARAM = new Object[0]; + @Mock AuthzTrans trans; @Mock @@ -91,40 +90,72 @@ public class JU_Function { @Mock Question ques; + @Mock + Organization org; + + @Mock + CachedNSDAO nsDAO; + + @Mock + CachedRoleDAO roleDAO; + + @Mock + CachedPermDAO permDAO; + + @Mock + CachedCredDAO credDAO; + + @Mock + CachedUserRoleDAO userRoleDAO; + + @Mock + ApprovalDAO approvalDAO; + + @Mock + FutureDAO futureDAO; + @Before public void setUp() throws APIException, IOException { initMocks(this); - } + Mockito.doReturn(org).when(trans).org(); + Mockito.doReturn(nsDAO).when(ques).nsDAO(); + Mockito.doReturn(roleDAO).when(ques).roleDAO(); + Mockito.doReturn(permDAO).when(ques).permDAO(); + Mockito.doReturn(credDAO).when(ques).credDAO(); + Mockito.doReturn(userRoleDAO).when(ques).userRoleDAO(); + Mockito.doReturn(approvalDAO).when(ques).approvalDAO(); + Mockito.doReturn(futureDAO).when(ques).futureDAO(); - @Test - public void testCreateNs() { Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); + Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).info(); Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); + try { Define.set(access); } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); } + } + + @Test + public void testCreateNs() { Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); namespace.owner = owner; - - Organization org = Mockito.mock(Organization.class); - Mockito.doReturn(org).when(trans).org(); - + + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(roleDAO).read(trans, "test","test"); + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(permDAO).readByType(trans, "test","test"); + NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - Result retVal = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result retVal = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); + //setQuestion(ques, cachedNS); Function funcObj = new Function(trans, ques); Result result = funcObj.createNS(trans, namespace, true); @@ -133,16 +164,6 @@ public class JU_Function { @Test public void testCreateNsReadSuccess() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); @@ -157,13 +178,11 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - Result retVal = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result retVal = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); Function funcObj = new Function(trans, ques); Result result = funcObj.createNS(trans, namespace, true); @@ -172,16 +191,6 @@ public class JU_Function { @Test public void testCreateNsFromApprovaFalse() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); @@ -192,9 +201,9 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - Result retVal2 = new Result(data,1,"test",new String[0]); + Result retVal2 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal1.value, Access.write); Function funcObj = new Function(trans, ques); @@ -209,16 +218,6 @@ public class JU_Function { @Test public void testCreateNsownerLoop() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); @@ -265,16 +264,6 @@ public class JU_Function { @Test public void testCreateNsownerLoopException() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test"; List owner = new ArrayList(); @@ -297,7 +286,7 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,1,"test",new String[0]); + Result retVal1 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); Result result = funcObj.createNS(trans, namespace, true); @@ -305,195 +294,19 @@ public class JU_Function { assertTrue(result.details.contains("may not create Root Namespaces")); Mockito.doReturn(true).when(ques).isGranted(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - retVal1 = new Result(data,0,"test",new String[0]); + retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, null); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - Result retVal = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result retVal = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); result = funcObj.createNS(trans, namespace, true); assertTrue(24 == result.status); } - - public void setQuestion(Question ques, CachedNSDAO userRoleDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("nsDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, userRoleDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void setQuestionCredDao(Question ques, CachedCredDAO credDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("credDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, credDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void setQuestionUserRoleDao(Question ques, CachedUserRoleDAO credDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("userRoleDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, credDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - public void setQuestionCachedRoleDao(Question ques, CachedRoleDAO credDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("roleDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, credDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - public void setQuestionCachedPermDao(Question ques, CachedPermDAO credDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("permDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, credDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - public void setQuestionFutureDao(Question ques, FutureDAO futureDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("futureDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, futureDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - public void setQuestionApprovalDao(Question ques, ApprovalDAO approvalDaoObj) { - Field nsDaoField; - try { - nsDaoField = Question.class.getDeclaredField("approvalDAO"); - - nsDaoField.setAccessible(true); - // remove final modifier from field - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(nsDaoField, nsDaoField.getModifiers() & ~Modifier.FINAL); - - nsDaoField.set(ques, approvalDaoObj); - } catch (NoSuchFieldException | SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } + @Test public void testCreateNsAdminLoop() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); @@ -506,14 +319,12 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); - Result retVal = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - Mockito.doReturn(retVal).when(nsDaoObj).create(Mockito.any(), Mockito.any()); + Result retVal = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); + Mockito.doReturn(retVal).when(nsDAO).create(Mockito.any(), Mockito.any()); List dataObj = new ArrayList<>(); CredDAO.Data indData = new CredDAO.Data(); indData.id = "test"; @@ -526,10 +337,8 @@ public class JU_Function { e1.printStackTrace(); } dataObj.add(indData); - Result> retVal2 = new Result>(dataObj,0,"test",new String[0]); + Result> retVal2 = new Result>(dataObj,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(credDAO).readID(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); - setQuestionCredDao(ques, credDAO); Identity iden=Mockito.mock(Identity.class); try { @@ -541,6 +350,9 @@ public class JU_Function { e.printStackTrace(); } + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(roleDAO).read(trans, "test","test"); + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(permDAO).readByType(trans, "test","test"); + Function funcObj = new Function(trans, ques); Result result = funcObj.createNS(trans, namespace, true); assertTrue(result.status == 1); @@ -571,17 +383,12 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Result retVal = new Result(null,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - Mockito.doReturn(retVal).when(nsDaoObj).create(Mockito.any(), Mockito.any()); + Result retVal = new Result(null,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); + Mockito.doReturn(retVal).when(nsDAO).create(Mockito.any(), Mockito.any()); List dataObj = new ArrayList<>(); CredDAO.Data indData = new CredDAO.Data(); indData.id = "test"; @@ -615,25 +422,20 @@ public class JU_Function { indData5.type = "test"; dataObj5.add(indData5); - Result> retVal2 = new Result>(dataObj,0,"test",new String[0]); - Result> retVal6 = new Result>(dataObj,1,"test",new String[0]); - Result> retVal3 = new Result>(dataObj1,0,"test",new String[0]); - Result> retVal4 = new Result>(dataObj4,0,"test",new String[0]); - Result> retVal5 = new Result>(dataObj5,0,"test",new String[0]); + Result> retVal2 = new Result>(dataObj,0,"test",NO_PARAM); + Result> retVal6 = new Result>(dataObj,1,"test",NO_PARAM); + Result> retVal3 = new Result>(dataObj1,0,"test",NO_PARAM); + Result> retVal4 = new Result>(dataObj4,0,"test",NO_PARAM); + Result> retVal5 = new Result>(dataObj5,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(credDAO).readID(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal4).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal2).when(userRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal6).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal6).when(cachedRoleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); - Mockito.doReturn(retVal2).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal5).when(cachedPermDAO).readChildren(trans, "test", "test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readChildren(trans, "test", "test"); - setQuestion(ques, nsDaoObj); - setQuestionCredDao(ques, credDAO); - setQuestionUserRoleDao(ques, userRoleDAO); - setQuestionCachedRoleDao(ques, cachedRoleDAO); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal6).when(roleDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal6).when(roleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal2).when(permDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal5).when(permDAO).readChildren(trans, "test", "test"); + Mockito.doReturn(retVal5).when(permDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal3).when(roleDAO).readChildren(trans, "test", "test"); Identity iden=Mockito.mock(Identity.class); try { @@ -647,6 +449,9 @@ public class JU_Function { } Function funcObj = new Function(trans, ques); + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(roleDAO).read(trans, "test","test"); + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(permDAO).readByType(trans, "test","test"); + Result result = funcObj.createNS(trans, namespace, true); assertTrue(result.status == Status.ERR_ActionNotCompleted); @@ -654,16 +459,6 @@ public class JU_Function { @Test public void testCreateNsAdminLoopCreateSuc() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Namespace namespace = Mockito.mock(Namespace.class); namespace.name = "test.test"; List owner = new ArrayList(); @@ -676,17 +471,12 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Result retVal = new Result(null,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - Mockito.doReturn(retVal).when(nsDaoObj).create(Mockito.any(), Mockito.any()); + Result retVal = new Result(null,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); + Mockito.doReturn(retVal).when(nsDAO).create(Mockito.any(), Mockito.any()); List dataObj = new ArrayList<>(); CredDAO.Data indData = new CredDAO.Data(); indData.id = "test"; @@ -723,24 +513,19 @@ public class JU_Function { indData5.roles = rolesSet; dataObj5.add(indData5); - Result> retVal2 = new Result>(dataObj,0,"test",new String[0]); - Result> retVal3 = new Result>(dataObj1,0,"test",new String[0]); - Result> retVal4 = new Result>(dataObj4,0,"test",new String[0]); - Result> retVal5 = new Result>(dataObj5,0,"test",new String[0]); + Result> retVal2 = new Result>(dataObj,0,"test",NO_PARAM); + Result> retVal3 = new Result>(dataObj1,0,"test",NO_PARAM); + Result> retVal4 = new Result>(dataObj4,0,"test",NO_PARAM); + Result> retVal5 = new Result>(dataObj5,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(credDAO).readID(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal4).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal2).when(userRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal2).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal2).when(cachedRoleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); - Mockito.doReturn(retVal2).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal5).when(cachedPermDAO).readChildren(trans, "test", "test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readChildren(trans, "test", "test"); - setQuestion(ques, nsDaoObj); - setQuestionCredDao(ques, credDAO); - setQuestionUserRoleDao(ques, userRoleDAO); - setQuestionCachedRoleDao(ques, cachedRoleDAO); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal2).when(roleDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal2).when(roleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal2).when(permDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal5).when(permDAO).readChildren(trans, "test", "test"); + Mockito.doReturn(retVal5).when(permDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal3).when(roleDAO).readChildren(trans, "test", "test"); Identity iden=Mockito.mock(Identity.class); try { @@ -753,6 +538,9 @@ public class JU_Function { e.printStackTrace(); } + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(roleDAO).read(trans, "test","test"); + Mockito.doReturn(Result.err(Result.ERR_NotFound, "Not Found")).when(permDAO).readByType(trans, "test","test"); + Function funcObj = new Function(trans, ques); Result result = funcObj.createNS(trans, namespace, true); assertTrue(result.status == 0); @@ -761,77 +549,43 @@ public class JU_Function { @Test public void test4DeleteNs() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); - Result retVal = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result retVal = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); Function funcObj = new Function(trans, ques); Result result = funcObj.deleteNS(trans, "test"); assertTrue(result.status == Status.ERR_NsNotFound); } + @Test - public void test4DeleteCanMOveFail() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(true).when(trans).requested(REQD_TYPE.move); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); + public void test4DeleteCanMoveFail() { List dataAl = new ArrayList(); NsDAO.Data dataObj = new NsDAO.Data(); dataObj.type=1; dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result> retVal = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); Mockito.doReturn(false).when(ques).canMove(Mockito.any()); + Mockito.doReturn(retVal).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); Function funcObj = new Function(trans, ques); Result result = funcObj.deleteNS(trans, "test"); - assertTrue(result.status == Status.ERR_Denied); + assertTrue(result.status == Status.ERR_Security); } + @Test public void test4DeleteNsReadSuc() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); List dataAl = new ArrayList(); NsDAO.Data dataObj = new NsDAO.Data(); dataObj.type=1; dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result> retVal = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); - Result retVal2 = new Result(null,1,"test",new String[0]); + Result retVal2 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); Function funcObj = new Function(trans, ques); @@ -839,28 +593,17 @@ public class JU_Function { assertTrue(result.status == 1); } + @Test public void test4DeleteNsMayUserSuc() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); List dataAl = new ArrayList(); NsDAO.Data dataObj = new NsDAO.Data(); dataObj.type=1; dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result> retVal = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); - Result retVal2 = new Result(null,0,"test",new String[0]); + Result retVal2 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); Function funcObj = new Function(trans, ques); @@ -869,26 +612,19 @@ public class JU_Function { Mockito.doReturn(true).when(ques).isGranted(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); Mockito.doReturn(retVal2).when(credDAO).readNS(Mockito.any(), Mockito.anyString()); - setQuestionCredDao(ques, credDAO); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Result> retVal5 = new Result>(null,0,"test",new String[0]); - Mockito.doReturn(retVal5).when(cachedPermDAO).readNS(trans, "test"); - setQuestionCachedPermDao(ques, cachedPermDAO); + Result> retVal5 = new Result>(null,0,"test",NO_PARAM); + Mockito.doReturn(retVal5).when(permDAO).readNS(trans, "test"); - CachedUserRoleDAO cachedUserRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List dataObj4 = new ArrayList<>(); UserRoleDAO.Data indData4 = new UserRoleDAO.Data(); indData4.ns = "test"; indData4.rname = "test"; dataObj4.add(indData4); - Result> retVal4 = new Result>(dataObj4,0,"test",new String[0]); - Mockito.doReturn(retVal4).when(cachedUserRoleDAO).readByRole(trans, "test"); - setQuestionUserRoleDao(ques, cachedUserRoleDAO); + Result> retVal4 = new Result>(dataObj4,0,"test",NO_PARAM); + Mockito.doReturn(retVal4).when(userRoleDAO).readByRole(trans, "test"); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); List dataObj1 = new ArrayList<>(); RoleDAO.Data indData1 = new RoleDAO.Data(); indData1.ns = "test"; @@ -897,17 +633,14 @@ public class JU_Function { permsSet.add("test|test"); indData1.perms = permsSet; dataObj1.add(indData1); - Result> retVal3 = new Result>(dataObj1,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readNS(trans, "test"); - Mockito.doReturn(retVal3).when(cachedRoleDAO).read(trans, indData1); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Result> retVal3 = new Result>(dataObj1,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(roleDAO).readNS(trans, "test"); + Mockito.doReturn(retVal3).when(roleDAO).read(trans, indData1); funcObj = new Function(trans, ques); result = funcObj.deleteNS(trans, "test"); assertTrue(result.status == Status.ERR_DependencyExists); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - setQuestionUserRoleDao(ques, userRoleDAO); Mockito.doReturn(retVal4).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(true).when(trans).requested(REQD_TYPE.force); @@ -917,26 +650,14 @@ public class JU_Function { } @Test public void test4DeleteNsDrivensFailure() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); List dataAl = new ArrayList(); NsDAO.Data dataObj = new NsDAO.Data(); dataObj.type=1; dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result> retVal = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); - Result retVal2 = new Result(null,0,"test",new String[0]); + Result retVal2 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); Function funcObj = new Function(trans, ques); @@ -945,24 +666,19 @@ public class JU_Function { Mockito.doReturn(true).when(ques).isGranted(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); Mockito.doReturn(retVal2).when(credDAO).readNS(Mockito.any(), Mockito.anyString()); - setQuestionCredDao(ques, credDAO); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); List dataObj5 = new ArrayList<>(); PermDAO.Data indData5 = new PermDAO.Data(); indData5.ns = "test"; indData5.type = "test"; dataObj5.add(indData5); - Result> retVal5 = new Result>(dataObj5,0,"test",new String[0]); - Mockito.doReturn(retVal5).when(cachedPermDAO).readNS(trans, "test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).readNS(trans, "test.test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).read(trans, indData5); - setQuestionCachedPermDao(ques, cachedPermDAO); + Result> retVal5 = new Result>(dataObj5,0,"test",NO_PARAM); + Mockito.doReturn(retVal5).when(permDAO).readNS(trans, "test"); + Mockito.doReturn(retVal5).when(permDAO).readNS(trans, "test.test"); + Mockito.doReturn(retVal5).when(permDAO).read(trans, indData5); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); List dataObj1 = new ArrayList<>(); RoleDAO.Data indData1 = new RoleDAO.Data(); indData1.ns = "test"; @@ -971,11 +687,10 @@ public class JU_Function { permsSet.add("test|test"); indData1.perms = permsSet; dataObj1.add(indData1); - Result> retVal3 = new Result>(dataObj1,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readNS(trans, "test"); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readNS(trans, "test.test"); - Mockito.doReturn(retVal3).when(cachedRoleDAO).read(trans, indData1); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Result> retVal3 = new Result>(dataObj1,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(roleDAO).readNS(trans, "test"); + Mockito.doReturn(retVal3).when(roleDAO).readNS(trans, "test.test"); + Mockito.doReturn(retVal3).when(roleDAO).read(trans, indData1); funcObj = new Function(trans, ques); result = funcObj.deleteNS(trans, "test"); @@ -983,7 +698,7 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,1,"test",new String[0]); + Result retVal1 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); Mockito.doReturn(true).when(trans).requested(REQD_TYPE.force); @@ -991,33 +706,22 @@ public class JU_Function { result = funcObj.deleteNS(trans, "test.test"); assertTrue(result.status == 1); } + @Test public void test4DeleteNsWithDot() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedNSDAO nsDaoObj = Mockito.mock(CachedNSDAO.class); List dataAl = new ArrayList(); NsDAO.Data dataObj = new NsDAO.Data(); dataObj.type=1; dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal).when(nsDaoObj).read(Mockito.any(), Mockito.anyString()); - setQuestion(ques, nsDaoObj); + Result> retVal = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal).when(nsDAO).read(Mockito.any(), Mockito.anyString()); List nsDataList = new ArrayList(); CredDAO.Data nsData = new CredDAO.Data(); nsData.id="test"; nsDataList.add(nsData); - Result> retVal21 = new Result>(nsDataList,0,"test",new String[0]); - Result retVal2 = new Result(null,0,"test",new String[0]); + Result> retVal21 = new Result>(nsDataList,0,"test",NO_PARAM); + Result retVal2 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); Function funcObj = new Function(trans, ques); @@ -1026,35 +730,28 @@ public class JU_Function { Mockito.doReturn(true).when(ques).isGranted(Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); Mockito.doReturn(retVal21).when(credDAO).readNS(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal21).when(credDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); - setQuestionCredDao(ques, credDAO); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); List dataObj5 = new ArrayList<>(); PermDAO.Data indData5 = new PermDAO.Data(); indData5.ns = "test"; indData5.type = "test"; dataObj5.add(indData5); - Result> retVal5 = new Result>(dataObj5,0,"test",new String[0]); - Mockito.doReturn(retVal5).when(cachedPermDAO).readNS(trans, "test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).readNS(trans, "test.test"); - Mockito.doReturn(retVal5).when(cachedPermDAO).read(trans, indData5); - setQuestionCachedPermDao(ques, cachedPermDAO); + Result> retVal5 = new Result>(dataObj5,0,"test",new Object[0]); + Mockito.doReturn(retVal5).when(permDAO).readNS(trans, "test"); + Mockito.doReturn(retVal5).when(permDAO).readNS(trans, "test.test"); + Mockito.doReturn(retVal5).when(permDAO).read(trans, indData5); - CachedUserRoleDAO cachedUserRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List dataObj4 = new ArrayList<>(); UserRoleDAO.Data indData4 = new UserRoleDAO.Data(); indData4.ns = "test"; indData4.rname = "test"; dataObj4.add(indData4); - Result> retVal4 = new Result>(dataObj4,0,"test",new String[0]); - Mockito.doReturn(retVal4).when(cachedUserRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - Mockito.doReturn(retVal4).when(cachedUserRoleDAO).readByUser(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, cachedUserRoleDAO); + Result> retVal4 = new Result>(dataObj4,0,"test",NO_PARAM); + Mockito.doReturn(retVal4).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); + Mockito.doReturn(retVal4).when(userRoleDAO).readByUser(Mockito.any(), Mockito.anyString()); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); List dataObj1 = new ArrayList<>(); RoleDAO.Data indData1 = new RoleDAO.Data(); indData1.ns = "test"; @@ -1063,11 +760,10 @@ public class JU_Function { permsSet.add("test|test"); indData1.perms = permsSet; dataObj1.add(indData1); - Result> retVal3 = new Result>(dataObj1,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readNS(trans, "test"); - Mockito.doReturn(retVal3).when(cachedRoleDAO).readNS(trans, "test.test"); - Mockito.doReturn(retVal3).when(cachedRoleDAO).read(trans, indData1); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Result> retVal3 = new Result>(dataObj1,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(roleDAO).readNS(trans, "test"); + Mockito.doReturn(retVal3).when(roleDAO).readNS(trans, "test.test"); + Mockito.doReturn(retVal3).when(roleDAO).read(trans, indData1); funcObj = new Function(trans, ques); result = funcObj.deleteNS(trans, "test"); @@ -1075,7 +771,7 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); Mockito.doReturn(true).when(trans).requested(REQD_TYPE.force); @@ -1083,28 +779,17 @@ public class JU_Function { result = funcObj.deleteNS(trans, "test.test"); assertNull(result); } + @Test public void testGetOwners() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); // -// Result retVal2 = new Result(null,0,"test",new String[0]); +// Result retVal2 = new Result(null,0,"test",NO_PARAM); // Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); // Function funcObj = new Function(trans, ques); @@ -1115,43 +800,31 @@ public class JU_Function { @Test public void testDelOwner() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any( UserRoleDAO.Data.class)); - setQuestionUserRoleDao(ques, userRoleDAO); NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - Result retVal2 = new Result(data,1,"test",new String[0]); + Result retVal2 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal1.value, Access.write); Function funcObj = new Function(trans, ques); Result result = funcObj.delOwner(trans, "test", "test"); assertTrue(result.status == 1); - retVal1 = new Result(data,1,"test",new String[0]); + retVal1 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); result = funcObj.delOwner(trans, "test", "test"); assertTrue(result.status == 1); - retVal1 = new Result(data,0,"test",new String[0]); + retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); result = funcObj.delOwner(trans, "test", "test"); - retVal2 = new Result(data,0,"test",new String[0]); + retVal2 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal1.value, Access.write); result = funcObj.delOwner(trans, "test", "test"); // @@ -1159,26 +832,14 @@ public class JU_Function { @Test public void testGetAdmins() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); // -// Result retVal2 = new Result(null,0,"test",new String[0]); +// Result retVal2 = new Result(null,0,"test",NO_PARAM); // Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); // Function funcObj = new Function(trans, ques); @@ -1189,43 +850,31 @@ public class JU_Function { @Test public void testDelAdmin() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readUserInRole(Mockito.any(), Mockito.anyString(), Mockito.anyString()); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any( UserRoleDAO.Data.class)); - setQuestionUserRoleDao(ques, userRoleDAO); NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); - Result retVal2 = new Result(data,1,"test",new String[0]); + Result retVal2 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal1.value, Access.write); Function funcObj = new Function(trans, ques); Result result = funcObj.delAdmin(trans, "test", "test"); assertTrue(result.status == 1); - retVal1 = new Result(data,1,"test",new String[0]); + retVal1 = new Result(data,1,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); result = funcObj.delAdmin(trans, "test", "test"); assertTrue(result.status == 1); - retVal1 = new Result(data,0,"test",new String[0]); + retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); result = funcObj.delOwner(trans, "test", "test"); - retVal2 = new Result(data,0,"test",new String[0]); + retVal2 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal1.value, Access.write); result = funcObj.delAdmin(trans, "test", "test"); // @@ -1233,37 +882,21 @@ public class JU_Function { @Test public void testMovePerms() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retVal).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Mockito.doReturn(retVal).when(roleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Mockito.doReturn(retVal).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).create(Mockito.any(), Mockito.any()); NsDAO.Data nsDataObj = new NsDAO.Data(); nsDataObj.name="test"; StringBuilder sb = new StringBuilder(); - Result> retVal1 = new Result>(null,1,"test",new String[0]); + Result> retVal1 = new Result>(null,1,"test",NO_PARAM); invokeMovePerms(nsDataObj, sb, retVal1); @@ -1279,24 +912,24 @@ public class JU_Function { indData5.ns = "test"; indData5.type = "access"; dataObj5.add(indData5); - retVal1 = new Result>(dataObj5,0,"test",new String[0]); + retVal1 = new Result>(dataObj5,0,"test",NO_PARAM); - Result> retVal3 = new Result>(null,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal3).when(cachedPermDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Result> retVal3 = new Result>(null,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(permDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal3).when(permDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); NsSplit splitObj = new NsSplit("test", "test"); - Result retVal2 = new Result(splitObj,0,"test",new String[0]); + Result retVal2 = new Result(splitObj,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); invokeMovePerms(nsDataObj, sb, retVal1); - Result> retVal4 = new Result>(null,1,"test",new String[0]); - Mockito.doReturn(retVal4).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); + Result> retVal4 = new Result>(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal4).when(permDAO).create(Mockito.any(), Mockito.any()); invokeMovePerms(nsDataObj, sb, retVal1); - Mockito.doReturn(retVal3).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal4).when(cachedPermDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal3).when(permDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal4).when(permDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); invokeMovePerms(nsDataObj, sb, retVal1); } @@ -1325,35 +958,21 @@ public class JU_Function { @Test public void testMoveRoles() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retVal).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Mockito.doReturn(retVal).when(roleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal).when(roleDAO).create(Mockito.any(), Mockito.any()); NsDAO.Data nsDataObj = new NsDAO.Data(); nsDataObj.name="test"; StringBuilder sb = new StringBuilder(); - Result> retVal1 = new Result>(null,1,"test",new String[0]); + Result> retVal1 = new Result>(null,1,"test",NO_PARAM); invokeMoveRoles(nsDataObj, sb, retVal1); @@ -1369,24 +988,24 @@ public class JU_Function { indData5.ns = "test"; indData5.name = "admin"; dataObj5.add(indData5); - retVal1 = new Result>(dataObj5,0,"test",new String[0]); + retVal1 = new Result>(dataObj5,0,"test",NO_PARAM); - Result> retVal3 = new Result>(null,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal3).when(cachedRoleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Result> retVal3 = new Result>(null,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(roleDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal3).when(roleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); NsSplit splitObj = new NsSplit("test", "test"); - Result retVal2 = new Result(splitObj,0,"test",new String[0]); + Result retVal2 = new Result(splitObj,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); invokeMoveRoles(nsDataObj, sb, retVal1); - Result> retVal4 = new Result>(null,1,"test",new String[0]); - Mockito.doReturn(retVal4).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); + Result> retVal4 = new Result>(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal4).when(roleDAO).create(Mockito.any(), Mockito.any()); invokeMoveRoles(nsDataObj, sb, retVal1); - Mockito.doReturn(retVal3).when(cachedRoleDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal4).when(cachedRoleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); + Mockito.doReturn(retVal3).when(roleDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal4).when(roleDAO).delete(Mockito.any(), Mockito.any(), Mockito.anyBoolean()); invokeMoveRoles(nsDataObj, sb, retVal1); } @@ -1415,11 +1034,6 @@ public class JU_Function { @Test public void testCreatePerm() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(true).when(trans).requested(REQD_TYPE.force); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); try { Define.set(access); } catch (CadiException e) { @@ -1433,58 +1047,54 @@ public class JU_Function { perm.roles = rolesSet; // perm.type=1 dataAl.add(perm); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); - CachedRoleDAO userRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); - Mockito.doReturn(retVal).when(userRoleDAO).create(Mockito.any(), Mockito.any(RoleDAO.Data.class)); - setQuestionCachedRoleDao(ques, userRoleDAO); + Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any(UserRoleDAO.Data.class)); + Mockito.doReturn(retVal).when(userRoleDAO).create(Mockito.any(), Mockito.any(UserRoleDAO.Data.class)); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Mockito.doReturn(retVal).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal).when(cachedPermDAO).read(trans, perm); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal).when(permDAO).read(trans, perm); - Result retVal2 = new Result(null,1,"test",new String[0]); + Result retVal2 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,perm, Access.write); Function funcObj = new Function(trans, ques); Result result = funcObj.createPerm(trans, perm, false); assertTrue(result.status == 1); - retVal2 = new Result(null,0,"test",new String[0]); + retVal2 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,perm, Access.write); result = funcObj.createPerm(trans, perm, false); assertTrue(result.status == 1); NsSplit nsObj = new NsSplit("test","test"); - Result retValNs = new Result(nsObj,0,"test",new String[0]); + Result retValNs = new Result(nsObj,0,"test",NO_PARAM); Mockito.doReturn(retValNs).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal2).when(ques).mayUser(Mockito.any(), Mockito.anyString(),Mockito.any(RoleDAO.Data.class), Mockito.any()); + Result> retVal3 = Result.ok(new ArrayList<>()); + Mockito.doReturn(retVal3).when(roleDAO).read(Mockito.any(),Mockito.any(RoleDAO.Data.class)); + Result> retVal4 = Result.err(Result.ERR_NotFound,""); + Mockito.doReturn(retVal4).when(roleDAO).create(Mockito.any(),Mockito.any(RoleDAO.Data.class)); result = funcObj.createPerm(trans, perm, false); - Mockito.doReturn(retVal).when(cachedPermDAO).read(trans, perm); + Mockito.doReturn(retVal).when(permDAO).read(trans, perm); result = funcObj.createPerm(trans, perm, true); assertTrue(result.status == 1); - Mockito.doReturn(retVal2).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal2).when(permDAO).create(Mockito.any(), Mockito.any()); result = funcObj.createPerm(trans, perm, true); assertTrue(result.status == 0); Mockito.doReturn(false).when(trans).requested(REQD_TYPE.force); - Result> retVal1 = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal1).when(cachedPermDAO).read(trans, perm); + Result> retVal1 = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal1).when(permDAO).read(trans, perm); result = funcObj.createPerm(trans, perm, true); assertTrue(result.status == Status.ERR_ConflictAlreadyExists); } @Test public void testDeletePerm() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); try { Define.set(access); } catch (CadiException e) { @@ -1499,47 +1109,41 @@ public class JU_Function { // perm.type=1 dataAl.add(perm); - Result retVal2 = new Result(null,1,"test",new String[0]); + Result retVal2 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,perm, Access.write); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(dataAl,1,"test",new String[0]); + Result> retVal = new Result>(dataAl,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); Function funcObj = new Function(trans, ques); Result result = funcObj.deletePerm(trans, perm, true,false); assertTrue(result.status == 1); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); // Mockito.doReturn(retVal).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal).when(cachedPermDAO).read(trans, perm); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).read(trans, perm); result = funcObj.deletePerm(trans, perm, true,true); assertTrue(result.status == Status.ERR_PermissionNotFound); - retVal2 = new Result(null,0,"test",new String[0]); + retVal2 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,perm, Access.write); - Result> retVal3 = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedPermDAO).read(trans, perm); + Result> retVal3 = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(permDAO).read(trans, perm); NsSplit nsObj = new NsSplit("test","test"); - Result retValNs = new Result(nsObj,0,"test",new String[0]); + Result retValNs = new Result(nsObj,0,"test",NO_PARAM); Mockito.doReturn(retValNs).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retVal).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Mockito.doReturn(retVal).when(roleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); result = funcObj.deletePerm(trans, perm, true,false); assertNull(result); - Mockito.doReturn(retVal2).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); + Mockito.doReturn(retVal2).when(roleDAO).delPerm(Mockito.any(), Mockito.any(), Mockito.any()); result = funcObj.deletePerm(trans, perm, true,false); assertNull(result); @@ -1549,10 +1153,6 @@ public class JU_Function { @Test public void testDeleteRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); try { Define.set(access); } catch (CadiException e) { @@ -1577,48 +1177,42 @@ public class JU_Function { // perm.type=1 dataAl.add(role); - Result retVal2 = new Result(null,1,"test",new String[0]); + Result retVal2 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,role, Access.write); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); // -// Result retVal2 = new Result(null,0,"test",new String[0]); +// Result retVal2 = new Result(null,0,"test",NO_PARAM); // Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); // Function funcObj = new Function(trans, ques); Result result = funcObj.deleteRole(trans, role, true, false); assertTrue(result.status == 1); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - setQuestionCachedRoleDao(ques, cachedRoleDAO); - Result> retVal1 = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal1).when(cachedRoleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); + Result> retVal1 = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal1).when(roleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); NsSplit splitObj = new NsSplit("test", "test"); - Result retVal3 = new Result(splitObj,0,"test",new String[0]); + Result retVal3 = new Result(splitObj,0,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); // Mockito.doReturn(retVal).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal).when(cachedPermDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any()); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any()); result = funcObj.deleteRole(trans, role, true, true); assertNull(result); - Mockito.doReturn(retVal1).when(cachedPermDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any()); + Mockito.doReturn(retVal1).when(permDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any()); result = funcObj.deleteRole(trans, role, true, true); assertNull(result); - Mockito.doReturn(retVal).when(cachedRoleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); + Mockito.doReturn(retVal).when(roleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); result = funcObj.deleteRole(trans, role, true, true); assertTrue(result.status == Status.ERR_RoleNotFound); - retVal = new Result>(dataAlUser,0,"test",new String[0]); + retVal = new Result>(dataAlUser,0,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); result = funcObj.deleteRole(trans, role, false, true); assertTrue(result.status == Status.ERR_DependencyExists); @@ -1626,16 +1220,6 @@ public class JU_Function { @Test public void testAddPermToRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } List dataAlPerm = new ArrayList(); PermDAO.Data rolePerm = new PermDAO.Data(); Set rolesSetUser = new HashSet<>(); @@ -1658,20 +1242,18 @@ public class JU_Function { NsDAO.Data nsObj1 = new NsDAO.Data(); nsObj1.name="test12"; - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - Result retVal2 = new Result(nsObj,0,"test",new String[0]); + Result retVal2 = new Result(nsObj,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, role.ns, NsType.COMPANY); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, rolePerm.ns, NsType.COMPANY); - Result retVal3 = new Result(null,1,"test",new String[0]); + Result retVal3 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).mayUser(trans, null,rolePerm, Access.write); Mockito.doReturn(retVal3).when(ques).mayUser(trans, null,role, Access.write); @@ -1679,45 +1261,41 @@ public class JU_Function { Result result = funcObj.addPermToRole(trans, role, rolePerm, false); assertTrue(result.status == 1); - retVal2 = new Result(nsObj,1,"test",new String[0]); + retVal2 = new Result(nsObj,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, role.ns, NsType.COMPANY); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, rolePerm.ns, NsType.COMPANY); result = funcObj.addPermToRole(trans, role, rolePerm, false); assertTrue(result.status == 1); role.ns="test2"; - retVal2 = new Result(nsObj,0,"test",new String[0]); + retVal2 = new Result(nsObj,0,"test",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, role.ns, NsType.COMPANY); result = funcObj.addPermToRole(trans, role, rolePerm, false); assertTrue(result.status == 1); - retVal2 = new Result(nsObj,0,"test1",new String[0]); + retVal2 = new Result(nsObj,0,"test1",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, role.ns, NsType.COMPANY); - Result retVal21 = new Result(nsObj1,0,"test1",new String[0]); + Result retVal21 = new Result(nsObj1,0,"test1",NO_PARAM); Mockito.doReturn(retVal21).when(ques).deriveFirstNsForType(trans, rolePerm.ns, NsType.COMPANY); result = funcObj.addPermToRole(trans, role, rolePerm, false); assertTrue(result.status == 1); - retVal3 = new Result(null,0,"test",new String[0]); + retVal3 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).mayUser(trans, null,rolePerm, Access.write); - retVal2 = new Result(nsObj,0,"test1",new String[0]); + retVal2 = new Result(nsObj,0,"test1",NO_PARAM); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, role.ns, NsType.COMPANY); Mockito.doReturn(retVal2).when(ques).deriveFirstNsForType(trans, rolePerm.ns, NsType.COMPANY); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); // Mockito.doReturn(retVal).when(cachedPermDAO).create(Mockito.any(), Mockito.any()); - Mockito.doReturn(retVal).when(cachedPermDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); result = funcObj.addPermToRole(trans, role, rolePerm, false); assertTrue(result.status == Status.ERR_PermissionNotFound); - Result> retValPerm= new Result>(dataAlPerm,0,"test1",new String[0]); - Mockito.doReturn(retValPerm).when(cachedPermDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); + Result> retValPerm= new Result>(dataAlPerm,0,"test1",NO_PARAM); + Mockito.doReturn(retValPerm).when(permDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retVal3).when(cachedRoleDAO).read(trans, role); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Mockito.doReturn(retVal3).when(roleDAO).read(trans, role); result = funcObj.addPermToRole(trans, role, rolePerm, true); assertTrue(result.status == 22); @@ -1726,36 +1304,26 @@ public class JU_Function { result = funcObj.addPermToRole(trans, role, rolePerm, true); assertTrue(result.status == 2); - retVal3 = new Result(null,0,"test",new String[0]); + retVal3 = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).mayUser(trans, null,role, Access.write); - Mockito.doReturn(retVal3).when(cachedRoleDAO).create(trans, role); + Mockito.doReturn(retVal3).when(roleDAO).create(trans, role); result = funcObj.addPermToRole(trans, role, rolePerm, true); // System.out.println(result.status); assertNull(result); - retVal3 = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retVal3).when(cachedRoleDAO).create(trans, role); + retVal3 = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retVal3).when(roleDAO).create(trans, role); result = funcObj.addPermToRole(trans, role, rolePerm, true); assertTrue(result.status == 1); - Result> retVal31 = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retVal31).when(cachedRoleDAO).read(trans, role); + Result> retVal31 = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retVal31).when(roleDAO).read(trans, role); result = funcObj.addPermToRole(trans, role, rolePerm, true); assertTrue(result.status == 7); } @Test public void testDelPermFromRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } List dataAlPerm = new ArrayList(); PermDAO.Data rolePerm = new PermDAO.Data(); Set rolesSetUser = new HashSet<>(); @@ -1771,17 +1339,15 @@ public class JU_Function { role.perms = rolesSet; dataAl.add(role); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - Result retValFail = new Result(null,1,"test",new String[0]); - Result retValSuc = new Result(null,0,"test",new String[0]); + Result retValFail = new Result(null,1,"test",NO_PARAM); + Result retValSuc = new Result(null,0,"test",NO_PARAM); Mockito.doReturn(retValFail).when(ques).mayUser(trans, null,rolePerm, Access.write); Mockito.doReturn(retValFail).when(ques).mayUser(trans, null,role, Access.write); @@ -1792,24 +1358,20 @@ public class JU_Function { Mockito.doReturn(retValFail).when(ques).mayUser(trans, null,rolePerm, Access.write); Mockito.doReturn(retValSuc).when(ques).mayUser(trans, null,role, Access.write); - CachedRoleDAO cachedRoleDAO = Mockito.mock(CachedRoleDAO.class); - Mockito.doReturn(retValFail).when(cachedRoleDAO).read(trans, role); - setQuestionCachedRoleDao(ques, cachedRoleDAO); + Mockito.doReturn(retValFail).when(roleDAO).read(trans, role); - CachedPermDAO cachedPermDAO = Mockito.mock(CachedPermDAO.class); - Mockito.doReturn(retVal).when(cachedPermDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); - setQuestionCachedPermDao(ques, cachedPermDAO); + Mockito.doReturn(retVal).when(permDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, false); assertTrue(result.status == 1); - Result> retValPermSuc = new Result>(dataAlPerm,0,"test",new String[0]); - Mockito.doReturn(retValPermSuc).when(cachedPermDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); + Result> retValPermSuc = new Result>(dataAlPerm,0,"test",NO_PARAM); + Mockito.doReturn(retValPermSuc).when(permDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, false); assertTrue(result.status == 1); - Result> retValRoleSuc = new Result>(dataAl,0,"test",new String[0]); - Mockito.doReturn(retValRoleSuc).when(cachedRoleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); + Result> retValRoleSuc = new Result>(dataAl,0,"test",NO_PARAM); + Mockito.doReturn(retValRoleSuc).when(roleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == Status.ERR_PermissionNotFound); @@ -1818,8 +1380,8 @@ public class JU_Function { rolesSet.add("null|null|null|null"); role.perms = rolesSet; dataAl.add(role); - Mockito.doReturn(retValRoleSuc).when(cachedRoleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); - Mockito.doReturn(retVal).when(cachedPermDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any(RoleDAO.Data.class)); + Mockito.doReturn(retValRoleSuc).when(roleDAO).read(Mockito.any(), Mockito.any(RoleDAO.Data.class)); + Mockito.doReturn(retVal).when(permDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any(RoleDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 1); @@ -1827,48 +1389,38 @@ public class JU_Function { result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 1); - Mockito.doReturn(retValRoleSuc).when(cachedPermDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any(RoleDAO.Data.class)); - Mockito.doReturn(retVal).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); + Mockito.doReturn(retValRoleSuc).when(permDAO).delRole(Mockito.any(), Mockito.any(),Mockito.any(RoleDAO.Data.class)); + Mockito.doReturn(retVal).when(roleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 1); - Mockito.doReturn(retValPermSuc).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); + Mockito.doReturn(retValPermSuc).when(roleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 0); - Mockito.doReturn(retVal).when(cachedPermDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); + Mockito.doReturn(retVal).when(permDAO).read(Mockito.any(), Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 0); - Mockito.doReturn(retVal).when(cachedRoleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); + Mockito.doReturn(retVal).when(roleDAO).delPerm(Mockito.any(), Mockito.any(),Mockito.any(PermDAO.Data.class)); result = funcObj.delPermFromRole(trans, role, rolePerm, true); assertTrue(result.status == 1); NsSplit splitObj = new NsSplit("test", "test"); - Result retVal3 = new Result(splitObj,0,"test",new String[0]); + Result retVal3 = new Result(splitObj,0,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retValFail).when(ques).mayUser(Mockito.any(), Mockito.anyString(),Mockito.any(RoleDAO.Data.class), Mockito.any()); Mockito.doReturn(retValFail).when(ques).mayUser(Mockito.any(), Mockito.anyString(),Mockito.any(PermDAO.Data.class), Mockito.any()); result = funcObj.delPermFromRole(trans, "test", rolePerm); assertTrue(result.status == 2); - retVal3 = new Result(null,1,"test",new String[0]); + retVal3 = new Result(null,1,"test",NO_PARAM); Mockito.doReturn(retVal3).when(ques).deriveNsSplit(Mockito.any(), Mockito.anyString()); result = funcObj.delPermFromRole(trans, "test", rolePerm); assertTrue(result.status == 1); } @Test public void testAddUserRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -1880,21 +1432,15 @@ public class JU_Function { Mockito.doReturn(org).when(trans).org(); Mockito.doReturn(Mockito.mock(GregorianCalendar.class)).when(org).expiration(Mockito.any(), Mockito.any(), Mockito.anyString()); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - CachedRoleDAO roleDAO = Mockito.mock(CachedRoleDAO.class); - Result> retVal = new Result>(null,1,"test",new String[0]); - Result> retValSuc = new Result>(urDataAl,0,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); + Result> retValSuc = new Result>(urDataAl,0,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any(UserRoleDAO.Data.class)); Mockito.doReturn(retVal).when(userRoleDAO).create(Mockito.any(), Mockito.any(UserRoleDAO.Data.class)); Mockito.doReturn(retValSuc).when(roleDAO).read(Mockito.any(), Mockito.anyString(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - setQuestionCachedRoleDao(ques, roleDAO); - - CachedCredDAO credDAO = Mockito.mock(CachedCredDAO.class); - Result> retVal2 = new Result>(null,1,"test",new String[0]); + + Result> retVal2 = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal2).when(credDAO).readID(Mockito.any(), Mockito.anyString()); - setQuestionCredDao(ques, credDAO); Function funcObj = new Function(trans, ques); Result result = funcObj.addUserRole(trans, urData); @@ -1906,7 +1452,7 @@ public class JU_Function { NsDAO.Data data = new NsDAO.Data(); data.name="test"; - Result retVal1 = new Result(data,0,"test",new String[0]); + Result retVal1 = new Result(data,0,"test",NO_PARAM); Mockito.doReturn(retVal1).when(ques).mayUser(trans, null,retVal1.value, Access.write); Mockito.doReturn(retVal1).when(ques).deriveNs(trans, "test"); try { @@ -1952,18 +1498,9 @@ public class JU_Function { result = funcObj.addUserRole(trans, "test", "test", "test"); assertTrue(result.status == 20); } + @Test public void testExtendUserRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -1972,18 +1509,14 @@ public class JU_Function { urData.expires=new Date(); urDataAl.add(urData); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - CachedRoleDAO roleDAO = Mockito.mock(CachedRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); - Result> retValSuc = new Result>(urDataAl,0,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); + Result> retValSuc = new Result>(urDataAl,0,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); Mockito.doReturn(retValSuc).when(roleDAO).read(Mockito.any(), Mockito.anyString(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); - setQuestionCachedRoleDao(ques, roleDAO); Organization org = Mockito.mock(Organization.class); Mockito.doReturn(org).when(trans).org(); @@ -2003,19 +1536,9 @@ public class JU_Function { assertTrue(result.status == Status.ERR_UserRoleNotFound); } + @SuppressWarnings("deprecation") @Test public void testGetUsersByRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -2023,9 +1546,8 @@ public class JU_Function { urData.user="test"; urData.expires=new Date(); urDataAl.add(urData); - Result> retVal = new Result>(urDataAl,0,"test",new String[0]); + Result> retVal = new Result>(urDataAl,0,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); Function funcObj = new Function(trans, ques); Result> result = funcObj.getUsersByRole(trans, "test", false); @@ -2041,17 +1563,6 @@ public class JU_Function { } @Test public void testDelUserRole() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -2059,15 +1570,14 @@ public class JU_Function { urData.user="test"; urData.expires=new Date(); urDataAl.add(urData); - Result> retVal = new Result>(urDataAl,0,"test",new String[0]); + Result> retVal = new Result>(urDataAl,0,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any( UserRoleDAO.Data.class)); - setQuestionUserRoleDao(ques, userRoleDAO); Function funcObj = new Function(trans, ques); Result result = funcObj.delUserRole(trans, "test", "test", "test"); assertNull(result); - retVal = new Result>(urDataAl,1,"test",new String[0]); + retVal = new Result>(urDataAl,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any( UserRoleDAO.Data.class)); result = funcObj.delUserRole(trans, "test", "test", "test"); // assertTrue(result.status ==1); @@ -2076,22 +1586,11 @@ public class JU_Function { @Test public void testCreateFuture() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } FutureDAO.Data data = new FutureDAO.Data(); data.memo = "test"; NsDAO.Data nsd = new NsDAO.Data(); nsd.name = "test"; - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -2099,17 +1598,14 @@ public class JU_Function { urData.user="test"; urData.expires=new Date(); urDataAl.add(urData); - Result> retVal = new Result>(urDataAl,0,"test",new String[0]); - Result> retValFail = new Result>(urDataAl,1,"test",new String[0]); + Result> retVal = new Result>(urDataAl,0,"test",NO_PARAM); + Result> retValFail = new Result>(urDataAl,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).read(Mockito.any(), Mockito.any( UserRoleDAO.Data.class)); - setQuestionUserRoleDao(ques, userRoleDAO); Function funcObj = new Function(trans, ques); Result result = funcObj.createFuture(trans, data, "test", "test", nsd, FUTURE_OP.A); assertTrue(result.status == 20); - Organization org = Mockito.mock(Organization.class); - Mockito.doReturn(org).when(trans).org(); Identity iden=Mockito.mock(Identity.class); try { Mockito.doReturn(iden).when(org).getIdentity(trans, "test"); @@ -2120,17 +1616,13 @@ public class JU_Function { } FutureDAO.Data futureData = new FutureDAO.Data(); data.memo = "test"; - FutureDAO futureDaoObj = Mockito.mock(FutureDAO.class); - Result retValFuture = new Result(futureData,0,"test",new String[0]); - Mockito.doReturn(retValFuture).when(futureDaoObj).create(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyString()); - setQuestionFutureDao(ques, futureDaoObj); + Result retValFuture = new Result(futureData,0,"test",NO_PARAM); + Mockito.doReturn(retValFuture).when(futureDAO).create(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyString()); ApprovalDAO.Data approvalData = new ApprovalDAO.Data(); data.memo = "test"; - ApprovalDAO approvalDaoObj = Mockito.mock(ApprovalDAO.class); - Result retValApproval = new Result(approvalData,0,"test",new String[0]); - Mockito.doReturn(retValApproval).when(approvalDaoObj).create(Mockito.any(), Mockito.any( ApprovalDAO.Data.class)); - setQuestionApprovalDao(ques, approvalDaoObj); + Result retValApproval = new Result(approvalData,0,"test",NO_PARAM); + Mockito.doReturn(retValApproval).when(approvalDAO).create(Mockito.any(), Mockito.any( ApprovalDAO.Data.class)); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); result = funcObj.createFuture(trans, data, "test", "test", nsd, FUTURE_OP.A); @@ -2162,25 +1654,14 @@ public class JU_Function { result = funcObj.createFuture(trans, data, "test", "test", nsd, FUTURE_OP.C); assertTrue(result.status == 0); - retValApproval = new Result(null,1,"test",new String[0]); - Mockito.doReturn(retValApproval).when(approvalDaoObj).create(Mockito.any(), Mockito.any( ApprovalDAO.Data.class)); + retValApproval = new Result(null,1,"test",NO_PARAM); + Mockito.doReturn(retValApproval).when(approvalDAO).create(Mockito.any(), Mockito.any( ApprovalDAO.Data.class)); result = funcObj.createFuture(trans, data, "test", "test", nsd, FUTURE_OP.A); assertTrue(result.status == 8); } @Test public void testUbLookup() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } Object[] objArr = new Object[10]; - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); List urDataAl = new ArrayList<>(); UserRoleDAO.Data urData = new UserRoleDAO.Data(); urData.ns="test"; @@ -2188,10 +1669,9 @@ public class JU_Function { urData.user="test"; urData.expires=new Date(); urDataAl.add(urData); - Result> retVal = new Result>(urDataAl,0,"test",new String[0]); - Result> retValFail = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(urDataAl,0,"test",NO_PARAM); + Result> retValFail = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).read(trans, objArr); - setQuestionUserRoleDao(ques, userRoleDAO); Function funcObj = new Function(trans, ques); funcObj.urDBLookup.get(trans, objArr); @@ -2202,17 +1682,6 @@ public class JU_Function { @Test public void testPerformFutureOp() { - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).error(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).debug(); - Mockito.doReturn(Mockito.mock(LogTarget.class)).when(trans).info(); - Mockito.doReturn(Mockito.mock(Properties.class)).when(access).getProperties(); - Mockito.doReturn("test.test").when(access).getProperty(Config.AAF_ROOT_NS,"org.osaaf.aaf"); - try { - Define.set(access); - } catch (CadiException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } FutureDAO.Data futureDataDaoObj = new FutureDAO.Data(); futureDataDaoObj.memo="test"; futureDataDaoObj.target = "test"; @@ -2240,21 +1709,17 @@ public class JU_Function { FutureDAO.Data futureData = new FutureDAO.Data(); // data.memo = "test"; - FutureDAO futureDaoObj = Mockito.mock(FutureDAO.class); - Result retValFuture = new Result(futureData,0,"test",new String[0]); - Mockito.doReturn(retValFuture).when(futureDaoObj).delete(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyBoolean()); - setQuestionFutureDao(ques, futureDaoObj); + Result retValFuture = new Result(futureData,0,"test",NO_PARAM); + Mockito.doReturn(retValFuture).when(futureDAO).delete(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyBoolean()); - CachedUserRoleDAO userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); // List dataAl = new ArrayList(); // NsDAO.Data dataObj = new NsDAO.Data(); // dataObj.type=1; // dataAl.add(dataObj); - Result> retVal = new Result>(null,1,"test",new String[0]); + Result> retVal = new Result>(null,1,"test",NO_PARAM); Mockito.doReturn(retVal).when(userRoleDAO).readByRole(Mockito.any(), Mockito.anyString()); - setQuestionUserRoleDao(ques, userRoleDAO); // -// Result retVal2 = new Result(null,0,"test",new String[0]); +// Result retVal2 = new Result(null,0,"test",NO_PARAM); // Mockito.doReturn(retVal2).when(ques).mayUser(trans, null,retVal.value.get(0), Access.write); // Function funcObj = new Function(trans, ques); @@ -2291,8 +1756,8 @@ public class JU_Function { result = funcObj.performFutureOp(trans, FUTURE_OP.A, futureDataDaoObj, lookupApprovalObj, lookupUserObj); assertTrue(result.status == 0); - retValFuture = new Result(futureData,1,"test",new String[0]); - Mockito.doReturn(retValFuture).when(futureDaoObj).delete(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyBoolean()); + retValFuture = new Result(futureData,1,"test",NO_PARAM); + Mockito.doReturn(retValFuture).when(futureDAO).delete(Mockito.any(), Mockito.any( FutureDAO.Data.class), Mockito.anyBoolean()); result = funcObj.performFutureOp(trans, FUTURE_OP.A, futureDataDaoObj, lookupApprovalObj, lookupUserObj); System.out.println(result); assertTrue(result.status == 0); diff --git a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_PermLookup.java b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_PermLookup.java index e63d4b52..9313af7a 100644 --- a/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_PermLookup.java +++ b/auth/auth-cass/src/test/java/org/onap/aaf/auth/dao/hl/JU_PermLookup.java @@ -64,12 +64,21 @@ public class JU_PermLookup { @Mock Access access; + + @Mock + CachedRoleDAO roleDAO; + + @Mock + CachedUserRoleDAO userRoleDAO; Function f; @Before public void setUp() throws Exception { initMocks(this); + Mockito.doReturn(userRoleDAO).when(q).userRoleDAO(); + Mockito.doReturn(roleDAO).when(q).roleDAO(); + try { Mockito.doReturn("0.0").when(access).getProperty("aaf_root_ns","org.osaaf.aaf"); Mockito.doReturn(new Properties()).when(access).getProperties(); @@ -106,18 +115,18 @@ public class JU_PermLookup { } - @Test - public void testPerm() { - - PermLookup cassExecutorObj =PermLookup.get(trans, q,""); - -// System.out.println(cassExecutorObj); -// assertFalse(retVal); - } +// @Test +// public void testPerm() { +// +// PermLookup cassExecutorObj =PermLookup.get(trans, q,""); +// +//// System.out.println(cassExecutorObj); +//// assertFalse(retVal); +// } @Test public void testGetUserRole() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -126,7 +135,7 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(true).when(retVal1).isOKhasData(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getUserRoles(); @@ -136,12 +145,12 @@ public class JU_PermLookup { @Test public void testGetUserRolesFirstIf() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); Mockito.doReturn(false).when(retVal1).isOKhasData(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getUserRoles(); @@ -151,7 +160,7 @@ public class JU_PermLookup { @Test public void testGetUserRolesSecondIf() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -164,7 +173,7 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(true).when(retVal1).isOKhasData(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getUserRoles(); @@ -178,7 +187,7 @@ public class JU_PermLookup { @Test public void testGetRole() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -188,7 +197,7 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(false).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getRoles(); @@ -198,8 +207,7 @@ public class JU_PermLookup { @Test public void testGetRoleFirstIf() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - q.roleDAO = Mockito.mock(CachedRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -211,8 +219,8 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(false).when(retVal1).isOKhasData(); Mockito.doReturn(false).when(retVal1).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); - Mockito.doReturn(retVal1).when(q.roleDAO).read(trans,"",""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(roleDAO).read(trans,"",""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getRoles(); @@ -222,8 +230,7 @@ public class JU_PermLookup { @Test public void testGetRoleSecondIf() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - q.roleDAO = Mockito.mock(CachedRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -235,8 +242,8 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(false).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); - Mockito.doReturn(retVal1).when(q.roleDAO).read(trans,"",""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(roleDAO).read(trans,"",""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getRoles(); userRoles = cassExecutorObj.getRoles(); @@ -246,12 +253,12 @@ public class JU_PermLookup { } @Test public void testGetPerms() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); Mockito.doReturn(false).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getPermNames(); userRoles = cassExecutorObj.getPermNames(); @@ -261,7 +268,7 @@ public class JU_PermLookup { } @Test public void testGetPermsRrldOk() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); + @SuppressWarnings("unchecked") Result> retVal1 = Mockito.mock(Result.class); retVal1.value = new ArrayList(); UserRoleDAO.Data dataObj = Mockito.mock( UserRoleDAO.Data.class); @@ -271,7 +278,7 @@ public class JU_PermLookup { retVal1.value.add(dataObj); Mockito.doReturn(false).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); Result> userRoles = cassExecutorObj.getPermNames(); @@ -280,10 +287,9 @@ public class JU_PermLookup { } + @SuppressWarnings("unchecked") @Test public void testGetPerm() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - q.roleDAO = Mockito.mock(CachedRoleDAO.class); Result> retVal1 = Mockito.mock(Result.class); Result> retVal2 = Mockito.mock(Result.class); @@ -316,8 +322,8 @@ public class JU_PermLookup { Mockito.doReturn(true).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); Mockito.doReturn(true).when(retVal2).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); - Mockito.doReturn(retVal2).when(q.roleDAO).read(trans,"",""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal2).when(roleDAO).read(trans,"",""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); @@ -330,10 +336,9 @@ public class JU_PermLookup { assertEquals(0,userRoles.status); } + @SuppressWarnings("unchecked") @Test public void testGetPermFalse() { - q.userRoleDAO = Mockito.mock(CachedUserRoleDAO.class); - q.roleDAO = Mockito.mock(CachedRoleDAO.class); Result> retVal1 = Mockito.mock(Result.class); Result> retVal2 = Mockito.mock(Result.class); @@ -366,8 +371,8 @@ public class JU_PermLookup { Mockito.doReturn(true).when(retVal1).isOKhasData(); Mockito.doReturn(true).when(retVal1).isOK(); Mockito.doReturn(true).when(retVal2).isOK(); - Mockito.doReturn(retVal1).when(q.userRoleDAO).readByUser(trans,""); - Mockito.doReturn(retVal2).when(q.roleDAO).read(trans,"",""); + Mockito.doReturn(retVal1).when(userRoleDAO).readByUser(trans,""); + Mockito.doReturn(retVal2).when(roleDAO).read(trans,"",""); PermLookup cassExecutorObj =PermLookup.get(trans, q,""); diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java index b7dd069d..a0a97241 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/ca/JscepCA.java @@ -35,18 +35,16 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.jscep.client.Client; import org.jscep.client.ClientException; import org.jscep.client.EnrollmentResponse; -import org.jscep.client.verification.CertificateVerifier; import org.onap.aaf.auth.cm.cert.BCFactory; import org.onap.aaf.auth.cm.cert.CSRMeta; import org.onap.aaf.cadi.Access; -import org.onap.aaf.cadi.LocatorException; import org.onap.aaf.cadi.Access.Level; import org.onap.aaf.cadi.Locator.Item; +import org.onap.aaf.cadi.LocatorException; import org.onap.aaf.cadi.configure.CertException; import org.onap.aaf.cadi.locator.HotPeerLocator; import org.onap.aaf.misc.env.Env; diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java index 3ff88d27..2b9204c9 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/mapper/Mapper2_0.java @@ -24,6 +24,7 @@ package org.onap.aaf.auth.cm.mapper; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.onap.aaf.auth.cm.data.CertDrop; import org.onap.aaf.auth.cm.data.CertRenew; @@ -35,7 +36,6 @@ import org.onap.aaf.auth.dao.cass.ArtiDAO.Data; import org.onap.aaf.auth.dao.cass.CertDAO; import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.layer.Result; -import org.onap.aaf.cadi.util.FQI; import org.onap.aaf.cadi.util.Vars; import aaf.v2_0.Error; @@ -208,39 +208,46 @@ public class Mapper2_0 implements Mapper { List ladd = new ArrayList<>(); for (Artifact arti : artifacts.getArtifact()) { ArtiDAO.Data data = new ArtiDAO.Data(); - data.mechid = arti.getMechid(); - data.machine = arti.getMachine(); + data.mechid = trim(arti.getMechid()); + data.machine = trim(arti.getMachine()); + Set ss = data.type(true); + if(arti.getType()!=null) { + for(String t : arti.getType()) { + ss.add(t.trim()); + } + } data.type(true).addAll(arti.getType()); - data.ca = arti.getCa(); - data.dir = arti.getDir(); - data.os_user = arti.getOsUser(); + data.ca = trim(arti.getCa()); + data.dir = trim(arti.getDir()); + data.os_user = trim(arti.getOsUser()); // Optional (on way in) - data.ns = arti.getNs(); + data.ns = trim(arti.getNs()); data.renewDays = arti.getRenewDays(); - data.notify = arti.getNotification(); + data.notify = trim(arti.getNotification()); // Ignored on way in for create/update - data.sponsor = arti.getSponsor(); + data.sponsor = trim(arti.getSponsor()); data.expires = null; - - // Derive Optional Data from Machine (Domain) if exists - if (data.machine!=null) { - if (data.ca==null) { - if (data.machine.endsWith(".att.com")) { - data.ca = "aaf"; // default - } - } - if (data.ns==null ) { - data.ns=FQI.reverseDomain(data.machine); - } + ss = data.sans(true); + if(arti.getSans()!=null) { + for(String s : arti.getSans()) { + ss.add(s.trim()); + } } - data.sans(true).addAll(arti.getSans()); ladd.add(data); } return ladd; } - /* (non-Javadoc) + private String trim(String s) { + if(s==null) { + return s; + } else { + return s.trim(); + } + } + + /* (non-Javadoc) * @see org.onap.aaf.auth.cm.mapper.Mapper#fromArtifacts(org.onap.aaf.auth.layer.test.Result) */ @Override diff --git a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/validation/CertmanValidator.java b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/validation/CertmanValidator.java index bb157a2e..f85eb44e 100644 --- a/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/validation/CertmanValidator.java +++ b/auth/auth-certman/src/main/java/org/onap/aaf/auth/cm/validation/CertmanValidator.java @@ -72,6 +72,9 @@ public class CertmanValidator extends Validator{ } else { for (ArtiDAO.Data a : list) { allRequired(a); + if(a.dir!=null && a.dir.startsWith("/tmp")) { + msg("Certificates may not be deployed into /tmp directory (they will be removed at a random time by O/S)"); + } } } } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java index 49fd4869..6ca09213 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/Cmd.java @@ -406,6 +406,7 @@ public abstract class Cmd { return i; } } + pw().printf("%s is not a valid cmd\n",test); throw new CadiException(build(new StringBuilder("Invalid Option: "),null).toString()); } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/perm/Grant.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/perm/Grant.java index ca958c20..f27a2609 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/perm/Grant.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/perm/Grant.java @@ -43,7 +43,7 @@ import aaf.v2_0.RolePermRequest; * */ public class Grant extends Cmd { - private static final String[] options = {"grant","ungrant","setTo"}; + private static final String[] options = {"grant","ungrant"}; public Grant(Perm parent) { super(parent,null, @@ -51,7 +51,7 @@ public class Grant extends Cmd { new Param("type",true), new Param("instance",true), new Param("action",true), - new Param("role[,role]* (!REQ S)",false) + new Param("role[,role]*",false) ); } @@ -74,63 +74,46 @@ public class Grant extends Cmd { Future frpr = null; - if (option != 2) { - String[] roles = args[idx++].split(","); - String strA; - String strB; - for (String role : roles) { - rpr.setRole(role); - if (option==0) { - // You can request to Grant Permission to a Role - setQueryParamsOn(client); - frpr = client.create( - "/authz/role/perm", - getDF(RolePermRequest.class), - rpr - ); - strA = "Granted Permission ["; - strB = "] to Role ["; - } else { - // You can request to UnGrant Permission to a Role - setQueryParamsOn(client); - frpr = client.delete( - "/authz/role/" + role + "/perm", - getDF(RolePermRequest.class), - rpr - ); - strA = "UnGranted Permission ["; - strB = "] from Role ["; - } - if (frpr.get(AAFcli.timeout())) { - pw().println(strA + pk.getType() + '|' + pk.getInstance() + '|' + pk.getAction() - + strB + role +']'); - } else { - if (frpr.code()==202) { - pw().print("Permission Role "); - pw().print(option==0?"Granted":"Ungranted"); - pw().println(" Accepted, but requires Approvals before actualizing"); - } else { - error(frpr); - idx=Integer.MAX_VALUE; - } - } + String[] roles = args[idx++].split(","); + String strA; + String strB; + for (String role : roles) { + rpr.setRole(role); + if (option==0) { + // You can request to Grant Permission to a Role + setQueryParamsOn(client); + frpr = client.create( + "/authz/role/perm", + getDF(RolePermRequest.class), + rpr + ); + strA = "Granted Permission ["; + strB = "] to Role ["; + } else { + // You can request to UnGrant Permission to a Role + setQueryParamsOn(client); + frpr = client.delete( + "/authz/role/" + role + "/perm", + getDF(RolePermRequest.class), + rpr + ); + strA = "UnGranted Permission ["; + strB = "] from Role ["; } - } else { - String allRoles = ""; - if (idx < args.length) - allRoles = args[idx++]; - - rpr.setRole(allRoles); - frpr = client.update( - "/authz/role/perm", - getDF(RolePermRequest.class), - rpr); if (frpr.get(AAFcli.timeout())) { - pw().println("Set Permission's Roles to [" + allRoles + "]"); + pw().println(strA + pk.getType() + '|' + pk.getInstance() + '|' + pk.getAction() + + strB + role +']'); } else { - error(frpr); - } - } + if (frpr.code()==202) { + pw().print("Permission Role "); + pw().print(option==0?"Granted":"Ungranted"); + pw().println(" Accepted, but requires Approvals before actualizing"); + } else { + error(frpr); + idx=Integer.MAX_VALUE; + } + } + } return frpr==null?0:frpr.code(); } }); @@ -138,16 +121,11 @@ public class Grant extends Cmd { @Override public void detailedHelp(int indent, StringBuilder sb) { - detailLine(sb,indent,"Grant a Permission to a Role or Roles OR"); - detailLine(sb,indent,"Ungrant a Permission from a Role or Roles OR"); - detailLine(sb,indent,"Set a Permission's roles to roles supplied."); - detailLine(sb,indent+4,"WARNING: Roles supplied with setTo will be the ONLY roles attached to this permission"); - detailLine(sb,indent+8,"If no roles are supplied, permission's roles are reset."); + detailLine(sb,indent,"Grant a Permission to a Role or Roles OR"); + detailLine(sb,indent,"Ungrant a Permission from a Role or Roles"); detailLine(sb,indent,"see Create for definitions of type,instance and action"); api(sb,indent,HttpMethods.POST,"authz/role/perm",RolePermRequest.class,true); api(sb,indent,HttpMethods.DELETE,"authz/role//perm",RolePermRequest.class,false); - api(sb,indent,HttpMethods.PUT,"authz/role/perm",RolePermRequest.class,false); - } } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/role/User.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/role/User.java index 364b3980..45361a3f 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/role/User.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/role/User.java @@ -40,12 +40,12 @@ import aaf.v2_0.UserRoleRequest; * */ public class User extends Cmd { - private final static String[] options = {"add","del","setTo","extend"}; + private final static String[] options = {"add","del","extend"}; public User(Role parent) { super(parent,"user", new Param(optionsToString(options),true), new Param("role",true), - new Param("id[,id]* (not required for setTo)",false)); + new Param("id[,id]*",false)); } @Override @@ -63,87 +63,62 @@ public class User extends Cmd { Future fp = null; - if (option != 2) { - String[] ids = args[idx++].split(","); - String verb=null,participle=null; - // You can request to be added or removed from role. - setQueryParamsOn(client); + String[] ids = args[idx++].split(","); + String verb=null,participle=null; + // You can request to be added or removed from role. + setQueryParamsOn(client); - for (String id: ids) { - id=fullID(id); - urr.setUser(id); - switch(option) { - case 0: - fp = client.create( - "/authz/userRole", - getDF(UserRoleRequest.class), - urr); - verb = "Added"; - participle = "] to Role [" ; - break; - case 1: - fp = client.delete( - "/authz/userRole/"+urr.getUser()+'/'+urr.getRole(), - Void.class); - verb = "Removed"; - participle = "] from Role [" ; - break; - case 3: - fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole()); - verb = "Extended"; - participle = "] in Role [" ; - break; + for (String id: ids) { + id=fullID(id); + urr.setUser(id); + switch(option) { + case 0: + fp = client.create( + "/authz/userRole", + getDF(UserRoleRequest.class), + urr); + verb = "Added"; + participle = "] to Role [" ; + break; + case 1: + fp = client.delete( + "/authz/userRole/"+urr.getUser()+'/'+urr.getRole(), + Void.class); + verb = "Removed"; + participle = "] from Role [" ; + break; + case 2: + fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole()); + verb = "Extended"; + participle = "] in Role [" ; + break; - default: // actually, should never get here... - throw new CadiException("Invalid action [" + action + ']'); - } - if (fp.get(AAFcli.timeout())) { - pw().print(verb); - pw().print(" User ["); - pw().print(urr.getUser()); - pw().print(participle); - pw().print(urr.getRole()); - pw().println(']'); - } else { - switch(fp.code()) { - case 202: - pw().print("User Role "); - pw().print(action); - pw().println(" is Accepted, but requires Approvals before actualizing"); - break; - case 404: - if (option==3) { - pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view"); - break; - } - default: - error(fp); - } - } + default: // actually, should never get here... + throw new CadiException("Invalid action [" + action + ']'); } - } else { - String allUsers = ""; - if (idx < args.length) - allUsers = args[idx++]; - StringBuilder finalUsers = new StringBuilder(); - for (String u : allUsers.split(",")) { - if (u != "") { - u=fullID(u); - if (finalUsers.length() > 0) finalUsers.append(","); - finalUsers.append(u); - } - } - - urr.setUser(finalUsers.toString()); - fp = client.update( - "/authz/userRole/role", - getDF(UserRoleRequest.class), - urr); if (fp.get(AAFcli.timeout())) { - pw().println("Set the Role to Users [" + allUsers + "]"); + pw().print(verb); + pw().print(" User ["); + pw().print(urr.getUser()); + pw().print(participle); + pw().print(urr.getRole()); + pw().println(']'); } else { - error(fp); - } + switch(fp.code()) { + case 202: + pw().print("User Role "); + pw().print(action); + pw().println(" is Accepted, but requires Approvals before actualizing"); + break; + case 404: + if (option==3) { + pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view"); + break; + } + default: + error(fp); + } + } } return fp==null?0:fp.code(); } @@ -152,18 +127,13 @@ public class User extends Cmd { @Override public void detailedHelp(int indent, StringBuilder sb) { - detailLine(sb,indent,"Add OR Delete a User to/from a Role OR"); - detailLine(sb,indent,"Set a User's Roles to the roles supplied"); + detailLine(sb,indent,"Add OR Delete a User to/from a Role OR extend Expiration"); detailLine(sb,indent+2,"role - Name of Role to create"); detailLine(sb,indent+2,"id(s) - ID or IDs to add to the Role"); sb.append('\n'); - detailLine(sb,indent+2,"Note: this is the same as \"user role add...\" except allows"); - detailLine(sb,indent+2,"assignment of role to multiple userss"); - detailLine(sb,indent+2,"WARNING: Users supplied with setTo will be the ONLY users attached to this role"); - detailLine(sb,indent+2,"If no users are supplied, the users attached to this role are reset."); api(sb,indent,HttpMethods.POST,"authz/userRole",UserRoleRequest.class,true); api(sb,indent,HttpMethods.DELETE,"authz/userRole//",Void.class,false); - api(sb,indent,HttpMethods.PUT,"authz/userRole/",UserRoleRequest.class,false); + api(sb,indent,HttpMethods.PUT,"authz/userRole/extend//",Void.class,false); } } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java index 6733989e..6d993284 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/List.java @@ -56,16 +56,26 @@ public class List extends BaseCmd { } return u1.getId().compareTo(u2.getId()); }); - String format = reportColHead("%-40s %-10s %-30s\n","User","Type","Expires"); + String format = reportColHead("%-48s %-5s %-11s %-16s\n","User","Type","Expires","Tag"); String date = "XXXX-XX-XX"; for (aaf.v2_0.Users.User user : sorted) { if (!aafcli.isTest()) { date = Chrono.dateOnlyStamp(user.getExpires()); } + String tag=null; + if(user.getType()<200) { + tag = user.getTag(); + } else { + tag = "\n\tfingerprint: " + user.getTag(); + } + if(tag==null) { + tag=""; + } pw().format(format, count? (Integer.valueOf(++idx) + ") " + user.getId()): user.getId(), org.onap.aaf.auth.cmd.ns.List.getType(user), - date); + date, + tag); } pw().println(); } diff --git a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Role.java b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Role.java index 4bc99366..4787cabc 100644 --- a/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Role.java +++ b/auth/auth-cmd/src/main/java/org/onap/aaf/auth/cmd/user/Role.java @@ -41,10 +41,10 @@ import aaf.v2_0.UserRoleRequest; * */ public class Role extends Cmd { - private static final String[] options = {"add", "del", "setTo","extend"}; + private static final String[] options = {"add", "del", "extend"}; public Role(User parent) { - super(parent, "role", new Param(optionsToString(options), true), new Param("user", true), new Param( - "role[,role]* (!REQ S)", false)); + super(parent, "role", new Param(optionsToString(options), true), new Param("user", true), + new Param("role[,role]*", false)); } @Override @@ -64,72 +64,57 @@ public class Role extends Cmd { Future fp = null; - if (option != 2) { - if (args.length < 5) { - throw new CadiException(build(new StringBuilder("Too few args: "), null).toString()); + if (args.length < 5) { + throw new CadiException(build(new StringBuilder("Too few args: "), null).toString()); + } + String[] roles = args[idx++].split(","); + for (String role : roles) { + String verb = null,participle=null; + urr.setRole(role); + // You can request to be added or removed from role. + setQueryParamsOn(client); + switch(option) { + case 0: + fp = client.create("/authz/userRole", getDF(UserRoleRequest.class), urr); + verb = "Added"; + participle = "] to User [" ; + break; + case 1: + fp = client.delete("/authz/userRole/" + urr.getUser() + '/' + urr.getRole(), Void.class); + verb = "Removed"; + participle = "] from User [" ; + break; + case 2: + fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole()); + verb = "Extended"; + participle = "] to User [" ; + break; + default: + throw new CadiException("Invalid action [" + key + ']'); } - String[] roles = args[idx++].split(","); - for (String role : roles) { - String verb = null,participle=null; - urr.setRole(role); - // You can request to be added or removed from role. - setQueryParamsOn(client); - switch(option) { - case 0: - fp = client.create("/authz/userRole", getDF(UserRoleRequest.class), urr); - verb = "Added"; - participle = "] to User [" ; - break; - case 1: - fp = client.delete("/authz/userRole/" + urr.getUser() + '/' + urr.getRole(), Void.class); - verb = "Removed"; - participle = "] from User [" ; - break; - case 3: - fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole()); - verb = "Extended"; - participle = "] to User [" ; + if (fp.get(AAFcli.timeout())) { + pw().print(verb); + pw().print(" Role ["); + pw().print(urr.getRole()); + pw().print(participle); + pw().print(urr.getUser()); + pw().println(']'); + } else { + switch(fp.code()) { + case 202: + pw().print("UserRole "); + pw().print(option == 0 ? "Creation" : option==1?"Deletion":"Extension"); + pw().println(" Accepted, but requires Approvals before actualizing"); break; - default: - throw new CadiException("Invalid action [" + key + ']'); - } - if (fp.get(AAFcli.timeout())) { - pw().print(verb); - pw().print(" Role ["); - pw().print(urr.getRole()); - pw().print(participle); - pw().print(urr.getUser()); - pw().println(']'); - } else { - switch(fp.code()) { - case 202: - pw().print("UserRole "); - pw().print(option == 0 ? "Creation" : option==1?"Deletion":"Extension"); - pw().println(" Accepted, but requires Approvals before actualizing"); + case 404: + if (option==3) { + pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view"); break; - case 404: - if (option==3) { - pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view"); - break; - } - default: - error(fp); } + default: + error(fp); } } - } else { - // option 2 is setTo command (an update call) - String allRoles = ""; - if (idx < args.length) - allRoles = args[idx++]; - - urr.setRole(allRoles); - fp = client.update("/authz/userRole/user", getDF(UserRoleRequest.class), urr); - if (fp.get(AAFcli.timeout())) { - pw().println("Set User's Roles to [" + allRoles + "]"); - } else { - error(fp); - } } return fp == null ? 0 : fp.code(); } @@ -138,18 +123,14 @@ public class Role extends Cmd { @Override public void detailedHelp(int indent, StringBuilder sb) { - detailLine(sb, indent, "Add OR Delete a User to/from a Role OR"); - detailLine(sb, indent, "Set a User's Roles to the roles supplied"); + detailLine(sb, indent, "Add or Delete a User to/from a Role OR extend Expiration"); detailLine(sb, indent + 2, "user - ID of User"); detailLine(sb, indent + 2, "role(s) - Role or Roles to which to add the User"); sb.append('\n'); - detailLine(sb, indent + 2, "Note: this is the same as \"role user add...\" except allows"); - detailLine(sb, indent + 2, "assignment of user to multiple roles"); - detailLine(sb, indent + 2, "WARNING: Roles supplied with setTo will be the ONLY roles attached to this user"); - detailLine(sb, indent + 2, "If no roles are supplied, user's roles are reset."); api(sb, indent, HttpMethods.POST, "authz/userRole", UserRoleRequest.class, true); api(sb, indent, HttpMethods.DELETE, "authz/userRole//", Void.class, false); - api(sb, indent, HttpMethods.PUT, "authz/userRole/", UserRoleRequest.class, false); + api(sb,indent,HttpMethods.PUT,"authz/userRole/extend//",Void.class,false); + } } diff --git a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java index 8e252c9e..ebd5f5f9 100644 --- a/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java +++ b/auth/auth-cmd/src/test/java/org/onap/aaf/auth/cmd/test/perm/JU_Grant.java @@ -92,36 +92,20 @@ public class JU_Grant { @Test public void testExecError() throws APIException, LocatorException, CadiException, URISyntaxException { - grant._exec(0, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); + grant._exec(0, new String[] {"grant","type","instance","action","role"}); } @Test public void testExecSuccess1() throws APIException, LocatorException, CadiException, URISyntaxException { when(futureMock.code()).thenReturn(202); - grant._exec(0, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); - grant._exec(1, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); + grant._exec(0, new String[] {"grant","type","instance","action","role"}); + } @Test public void testExecSuccess2() throws APIException, LocatorException, CadiException, URISyntaxException { when(futureMock.get(any(Integer.class))).thenReturn(true); - grant._exec(0, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); - } - - @Test - public void testExecSetToError() throws APIException, LocatorException, CadiException, URISyntaxException { - grant._exec(2, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); - } - - @Test - public void testExecSetToSuccess1() throws APIException, LocatorException, CadiException, URISyntaxException { - when(futureMock.get(any(Integer.class))).thenReturn(true); - grant._exec(2, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo"}); - } - - @Test - public void testExecSetToSuccess2() throws APIException, LocatorException, CadiException, URISyntaxException { - grant._exec(2, new String[] {"grant","ungrant","setTo","grant","ungrant","setTo","another"}); + grant._exec(0, new String[] {"grant","type","instance","action","role"}); } @Test diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java index 2bae29b5..0256c1bf 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java @@ -43,6 +43,8 @@ public interface AuthzTrans extends TransStore { public abstract AuthzTrans set(HttpServletRequest req); + public abstract HttpServletRequest hreq(); + public abstract String user(); public abstract void setUser(TaggedPrincipal p); diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java index aa6b038b..ce947be9 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java @@ -34,16 +34,16 @@ import org.onap.aaf.misc.env.LogTarget; import org.onap.aaf.misc.env.impl.BasicTrans; public class AuthzTransImpl extends BasicTrans implements AuthzTrans { + private static final String N_A = "n/a"; + private static final String BLANK = ""; + private HttpServletRequest hreq; private TaggedPrincipal user; - private String ip,agent,meth,path; - private int port; private Lur lur; private Organization org; private int mask; private Date now; public AuthzTransImpl(AuthzEnv env) { super(env); - ip="n/a"; org=null; mask=0; } @@ -53,12 +53,8 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public AuthzTrans set(HttpServletRequest req) { + hreq = req; user = (TaggedPrincipal)req.getUserPrincipal(); - ip = req.getRemoteAddr(); - port = req.getRemotePort(); - agent = req.getHeader("User-Agent"); - meth = req.getMethod(); - path = req.getPathInfo(); for (REQD_TYPE rt : REQD_TYPE.values()) { requested(rt,req); @@ -72,6 +68,10 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { org=null; return this; } + @Override + public HttpServletRequest hreq() { + return hreq; + } @Override public void setUser(TaggedPrincipal p) { @@ -83,7 +83,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public String user() { - return user==null?"n/a":user.getName(); + return user==null?N_A:user.getName(); } /** @@ -99,7 +99,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public String ip() { - return ip; + return hreq==null?N_A:hreq.getRemoteAddr(); } /** @@ -107,7 +107,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public int port() { - return port; + return hreq==null?0:hreq.getRemotePort(); } @@ -116,7 +116,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public String meth() { - return meth; + return hreq==null?"":hreq.getMethod(); } /* (non-Javadoc) @@ -124,7 +124,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public String path() { - return path; + return hreq==null?"":hreq.getPathInfo(); } /** @@ -132,7 +132,7 @@ public class AuthzTransImpl extends BasicTrans implements AuthzTrans { */ @Override public String agent() { - return agent; + return hreq==null?BLANK:hreq.getHeader("User-Agent"); } @Override diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java index 942a0e54..94a6aad5 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java @@ -135,6 +135,11 @@ public class NullTrans implements AuthzTrans { } @Override + public HttpServletRequest hreq() { + return null; + } + + @Override public String user() { return null; } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java index fa17f040..a269f24b 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java @@ -154,10 +154,10 @@ public class CachingFileAccess extends HttpCode2 && slash>=0 && key.substring(0,slash).equals(clear_command)) { resp.setHeader("Content-Type",typeMap.get("txt")); - if ("clear".equals(cmd)) { + if ("clear".equals(key.substring(slash+1))) { content.clear(); resp.setStatus(200/*HttpStatus.OK_200*/); } else { @@ -165,7 +165,7 @@ public class CachingFileAccess extends HttpCode0?key+'/'+cmd:key, null, checkInterval); + Content c = load(logT , web_path,key, null, checkInterval); if (c.attachmentOnly) { resp.setHeader("Content-disposition", "attachment"); } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java index c1bfd6ad..acca80ba 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java @@ -32,6 +32,9 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.onap.aaf.cadi.CadiException; +import org.onap.aaf.cadi.LocatorException; +import org.onap.aaf.misc.env.APIException; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; import org.onap.aaf.misc.env.Trans; @@ -122,6 +125,15 @@ public abstract class RServlet implements Servlet { return "RServlet for Jetty"; } + /** + * Allow Service to instantiate certain actions after service starts up + * @throws LocatorException + * @throws CadiException + * @throws APIException + */ + public void postStartup(String hostname, int port) throws APIException { + } + @Override public void destroy() { } diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java index 85b35ac7..d0fc1a3f 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java @@ -138,8 +138,9 @@ public abstract class TransFilter implements Filter { // Would need Cached Counter objects that are cleaned up on // use trans.checkpoint(resp.desc(),Env.ALWAYS); - if (resp.isFailedAttempt()) + if (resp.isFailedAttempt()) { trans.audit().log(resp.desc()); + } } } catch (Exception e) { trans.error().log(e); diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java index b3e2883d..0e8cb78d 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java @@ -67,8 +67,9 @@ public abstract class AbsServiceStarter rserv) throws Exception; - public abstract void _propertyAdjustment(); + + protected abstract void _start(RServlet rserv) throws Exception; + protected abstract void _propertyAdjustment(); public ENV env() { return service.env; @@ -103,10 +104,8 @@ public abstract class AbsServiceStarter ... registrants) { if (do_register) { diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java index 182956cf..bcc071a2 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java @@ -216,7 +216,8 @@ public class JettyServiceStarter ex access().printf(Level.INIT,"'aaf_no_register' is set. %s will not be registered with Locator", service.app_name); } access().printf(Level.INIT, "Starting Jetty Service for %s, version %s, on %s://%s:%d", service.app_name,service.app_version,protocol,hostname,port); - //server.join(); + + rserv.postStartup(hostname, port); } catch (Exception e) { access().log(e,"Error registering " + service.app_name); String doExit = access().getProperty("cadi_exitOnFailure", "true"); diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/Log4JLogIt.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/Log4JLogIt.java index fd0691b6..894f571d 100644 --- a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/Log4JLogIt.java +++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/Log4JLogIt.java @@ -22,7 +22,6 @@ package org.onap.aaf.auth.server; import java.io.File; import java.io.IOException; -import java.text.SimpleDateFormat; import org.apache.log4j.Logger; import org.onap.aaf.cadi.Access.Level; @@ -31,12 +30,11 @@ import org.onap.aaf.cadi.PropAccess.LogIt; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.misc.env.APIException; import org.onap.aaf.misc.env.log4j.LogFileNamer; +import org.onap.aaf.misc.env.util.Chrono; public class Log4JLogIt implements LogIt { protected static final String AAF_LOG4J_PREFIX = "aaf_log4j_prefix"; - - // Sonar says cannot be static... it's ok. not too many PropAccesses created. - private final SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + // Log4j does it's own date. Can't apparently turn it off. private final String service; private final String audit; @@ -104,30 +102,30 @@ public class Log4JLogIt implements LogIt { public void push(Level level, Object... elements) { switch(level) { case AUDIT: - laudit.warn(PropAccess.buildMsg(audit, iso8601, level, elements)); + laudit.warn(PropAccess.buildMsg(audit, Chrono.utcFmt, level, elements)); break; case INIT: - linit.warn(PropAccess.buildMsg(init, iso8601, level, elements)); + linit.warn(PropAccess.buildMsg(init, Chrono.utcFmt, level, elements)); break; case ERROR: - lservice.error(PropAccess.buildMsg(service, iso8601, level, elements)); + lservice.error(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; case WARN: - lservice.warn(PropAccess.buildMsg(service, iso8601, level, elements)); + lservice.warn(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; case INFO: - lservice.info(PropAccess.buildMsg(service, iso8601, level, elements)); + lservice.info(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; case DEBUG: - lservice.debug(PropAccess.buildMsg(service, iso8601, level, elements)); + lservice.debug(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; case TRACE: - ltrace.trace(PropAccess.buildMsg(service, iso8601, level, elements)); + ltrace.trace(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; case NONE: break; default: - lservice.info(PropAccess.buildMsg(service, iso8601, level, elements)); + lservice.info(PropAccess.buildMsg(service, Chrono.utcFmt, level, elements)); break; } diff --git a/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java b/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java index 26e49290..76041cef 100644 --- a/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java +++ b/auth/auth-fs/src/main/java/org/onap/aaf/auth/fs/AAF_FS.java @@ -59,8 +59,7 @@ public class AAF_FS extends AbsService { env.staticSlot(CachingFileAccess.CFA_WEB_PATH,"aaf_public_dir"); CachingFileAccess cfa = new CachingFileAccess(env); - route(env,GET,"/:key", cfa); - route(env,GET,"/:key/:cmd", cfa); + route(env,GET,"/:key*", cfa); final String aaf_locate_url = access.getProperty(Config.AAF_LOCATE_URL, null); if (aaf_locate_url == null) { access.printf(Level.WARN, "Redirection requires property %s",Config.AAF_LOCATE_URL); diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/cui/CUI.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/cui/CUI.java index 121ee3f7..7859b7cc 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/cui/CUI.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/cui/CUI.java @@ -76,11 +76,11 @@ public class CUI extends HttpCode { aafcli.gui(true); String cmdStr = cmd.toString(); - if (!cmdStr.contains("--help")) { - cmdStr = cmdStr.replaceAll("help", "--help"); + if (cmdStr.contains("--help")) { + cmdStr = cmdStr.replaceAll("--help", "help"); } - if (!cmdStr.contains("--version")) { - cmdStr = cmdStr.replaceAll("version", "--version"); + if (cmdStr.contains("--version")) { + cmdStr = cmdStr.replaceAll("--version", "version"); } try { aafcli.eval(cmdStr); diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java index 064a8a5c..359cb28b 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/AAF_GUI.java @@ -94,7 +94,7 @@ import certman.v1_0.Artifacts; import certman.v1_0.CertInfo; public class AAF_GUI extends AbsService implements State{ - private static final String AAF_GUI_THEME = "aaf_gui_theme"; + public static final String AAF_GUI_THEME = "aaf_gui_theme"; public static final String AAF_GUI_COPYRIGHT = "aaf_gui_copyright"; public static final String HTTP_SERVLET_REQUEST = "HTTP_SERVLET_REQUEST"; public static final int TIMEOUT = 60000; @@ -113,15 +113,18 @@ public class AAF_GUI extends AbsService implements State implements State(env)); + CachingFileAccess cfa = new CachingFileAccess(env); + //route(env,GET,"/"+env.get(sThemeWebPath)+"/:key*", cfa); + route(env,GET,"/theme/:key*", cfa); /////////////////////// aafCon = aafCon(); lur = aafCon.newLur(); diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/BreadCrumbs.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/BreadCrumbs.java index 4f1a7e82..621257b2 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/BreadCrumbs.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/BreadCrumbs.java @@ -37,7 +37,7 @@ import org.onap.aaf.misc.xgen.Mark; import org.onap.aaf.misc.xgen.html.HTMLGen; public class BreadCrumbs extends NamedCode { - private Page[] breadcrumbs; + Page[] breadcrumbs; public BreadCrumbs(Page ... pages) { super(false,"breadcrumbs"); diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Display.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Display.java index de1a8461..877974bd 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Display.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Display.java @@ -31,7 +31,6 @@ import org.onap.aaf.auth.env.AuthzTrans; import org.onap.aaf.auth.rserv.HttpCode; import org.onap.aaf.auth.rserv.HttpMethods; import org.onap.aaf.misc.env.Slot; -import org.onap.aaf.misc.xgen.html.HTMLGen; public class Display { private final Page get; diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Page.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Page.java index 1e067c44..8924ba26 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Page.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/Page.java @@ -27,21 +27,30 @@ import static org.onap.aaf.misc.xgen.html.HTMLGen.LI; import static org.onap.aaf.misc.xgen.html.HTMLGen.TITLE; import static org.onap.aaf.misc.xgen.html.HTMLGen.UL; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import org.onap.aaf.auth.common.Define; import org.onap.aaf.auth.env.AuthzEnv; import org.onap.aaf.auth.env.AuthzTrans; -import org.onap.aaf.auth.rserv.CachingFileAccess; +import org.onap.aaf.auth.gui.pages.Home; import org.onap.aaf.cadi.Permission; import org.onap.aaf.cadi.aaf.AAFPermission; +import org.onap.aaf.cadi.client.Holder; import org.onap.aaf.cadi.config.Config; import org.onap.aaf.cadi.principal.TaggedPrincipal; import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.Slot; import org.onap.aaf.misc.env.StaticSlot; import org.onap.aaf.misc.env.util.Split; @@ -71,11 +80,9 @@ public class Page extends HTMLCacheGen { public static final String PERM_NS = Define.ROOT_NS(); public static enum BROWSER {iPhone,html5,ie,ieOld}; - - public static final int MAX_LINE=20; + public static final int MAX_LINE = 20; protected static final String[] NO_FIELDS = new String[0]; - private static final String BROWSER_TYPE = "BROWSER_TYPE"; private final String bcName, bcUrl; @@ -151,14 +158,90 @@ public class Page extends HTMLCacheGen { private final int backdots; protected AuthzEnv env; private StaticSlot sTheme; + private static Map> themes; + private static Map themeProps; public PageCode(AuthzEnv env, int backdots, final ContentCode[] content) { this.content = content; this.backdots = backdots; browserSlot = env.slot(BROWSER_TYPE); - sTheme = env.staticSlot(CachingFileAccess.CFA_WEB_PATH); + sTheme = env.staticSlot(AAF_GUI.AAF_GUI_THEME); this.env = env; } + + private static synchronized List getThemeFiles(Env env, String theme) { + if(themes==null) { + themes = new TreeMap<>(); + File themeD = new File("theme"); + if(themeD.exists() && themeD.isDirectory()) { + for (File t : themeD.listFiles()) { + if(t.isDirectory()) { + List la = new ArrayList<>(); + for(File f : t.listFiles()) { + if(f.isFile()) { + if(f.getName().endsWith(".props")) { + Properties props; + if(themeProps == null) { + themeProps = new TreeMap<>(); + props = null; + } else { + props = themeProps.get(theme); + } + if(props==null) { + props = new Properties(); + themeProps.put(theme, props); + } + + try { + FileInputStream fis = new FileInputStream(f); + try { + props.load(fis); + } finally { + fis.close(); + } + } catch (IOException e) { + env.error().log(e); + } + } else { + la.add(f.getName()); + } + } + } + themes.put(t.getName(),la); + } + } + } + } + return themes.get(theme); + } + + protected Imports getImports(Env env, Holder theme, String defaultTheme, int backdots, BROWSER browser) { + List ls = getThemeFiles(env,theme.get()); + Imports imp = new Imports(backdots); + if(ls==null) { + theme.set(defaultTheme); + } + String prefix = "theme/" + theme.get() + '/'; + for(String f : ls) { + if(f.endsWith(".js")) { + imp.js(prefix + f); + } else if(f.endsWith(".css")) { + if(f.endsWith("iPhone.css")) { + if(BROWSER.iPhone.equals(browser)) { + imp.css(prefix + f); + } + } else if (f.endsWith("Desktop.css")){ + if(!BROWSER.iPhone.equals(browser)) { + imp.css(prefix + f); + } + // Make Console specific to Console page + } else if (!"console.js".equals(f)) { + imp.css(prefix + f); + } + } + } + return imp; + } @Override public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException { @@ -178,29 +261,34 @@ public class Page extends HTMLCacheGen { }); hgen.html(); final String title = env.getProperty(AAF_GUI_TITLE,"Authentication/Authorization Framework"); - final String theme = env.get(sTheme); + final String defaultTheme = env.get(sTheme); + final Holder hTheme = new Holder<>(defaultTheme); + Mark head = hgen.head(); hgen.leaf(TITLE).text(title).end(); - hgen.imports(new Imports(backdots).css(theme + "/aaf5.css") - .js(theme + "/comm.js") - .js(theme + "/console.js") - .js(theme + "/common.js")); cache.dynamic(hgen, new DynamicCode() { @Override public void code(AAF_GUI state, AuthzTrans trans, final Cache cache, final HTMLGen hgen) throws APIException, IOException { - switch(browser(trans,browserSlot)) { - case iPhone: - hgen.imports(new Imports(backdots).css(theme + "/aaf5iPhone.css")); - break; + BROWSER browser = browser(trans,browserSlot); + Cookie[] cookies = trans.hreq().getCookies(); + if(cookies!=null) { + for(Cookie c : cookies) { + if("aaf_theme".equals(c.getName())) { + hTheme.set(c.getValue()); + } + } + } + hgen.imports(getImports(env,hTheme,defaultTheme,backdots,browser)); + switch(browser) { case ie: case ieOld: hgen.js().text("document.createElement('header');") .text("document.createElement('nav');") .done(); - case html5: - hgen.imports(new Imports(backdots).css(theme + "/aaf5Desktop.css")); break; + default: } + } }); hgen.end(head); @@ -274,9 +362,62 @@ public class Page extends HTMLCacheGen { hgen.end(inner); - // Navigation - Using older Nav to work with decrepit IE versions + // Navigation - Using older Nav to work with decrepit IE versions Mark nav = hgen.divID("nav"); + cache.dynamic(hgen, new DynamicCode() { + @Override + public void code(AAF_GUI state, AuthzTrans trans,Cache cache, HTMLGen xgen) throws APIException, IOException { + Properties props = themeProps.get(hTheme.get()); + if(props!=null && "TRUE".equalsIgnoreCase(props.getProperty("main_menu_in_nav"))) { + xgen.incr("h2").text("Navigation").end(); + Mark mark = new Mark(); + boolean selected = isSelected(trans.path(),Home.HREF); + //trans.path().endsWith("home"); + xgen.incr(mark,HTMLGen.UL) + .incr(HTMLGen.LI,selected?"class=selected":"") + .incr(HTMLGen.A, "href=home") + .text("Home") + .end(2); + boolean noSelection = !selected; + for(String[] mi : Home.MENU_ITEMS) { + //selected = trans.path().endsWith(mi[0]); + if(noSelection) { + selected = isSelected(trans.path(),mi[2]); + noSelection = !selected; + } else { + selected = false; + } + xgen.incr(HTMLGen.LI,selected?"class=selected":"") + .incr(HTMLGen.A, "href="+mi[0]) + .text(mi[1]) + .end(2); + } + xgen.end(mark); + } + } + + private boolean isSelected(String path, String item) { + if(item.equals(path)) { + return true; + } else { + for(ContentCode c : content) { + if(c instanceof BreadCrumbs) { + Page[] bc = ((BreadCrumbs)c).breadcrumbs; + if(bc!=null) { + for(int i = bc.length-1;i>0;--i) { + if(bc[i].url().equals(item)) { + return true; + } + } + return false; + } + } + } + } + return false; + } + }); hgen.incr("h2").text("Related Links").end(); hgen.incr(UL); String aaf_help = env.getProperty(AAF_URL_AAF_HELP,null); @@ -398,6 +539,5 @@ public class Page extends HTMLCacheGen { return values.length<1?null:values[0]; } - } diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/Home.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/Home.java index e0a73dca..e7a643ca 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/Home.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/Home.java @@ -37,10 +37,25 @@ import org.onap.aaf.misc.xgen.html.HTMLGen; public class Home extends Page { public static final String HREF = "/gui/home"; + /* + * Relative path, Menu Name, Full Path + */ + public static String[][] MENU_ITEMS = new String[][] { + {"myperms","My Permissions","/gui/myperms"}, + {"myroles","My Roles","/gui/myroles"}, + {"ns","My Namespaces","/gui/ns"}, + {"approve","My Approvals","/gui/approve"}, + {"myrequests","My Pending Requests","/gui/myrequests"}, + // Enable later + // {"onboard","Onboarding"}, + {"passwd","Password Management","/gui/passwd"}, + {"cui","Command Prompt","/gui/cui"}, + {"api","AAF API","/gui/api"} + }; public Home(final AAF_GUI gui) throws APIException, IOException { super(gui.env,"Home",HREF, NO_FIELDS, new NamedCode(false,"content") { @Override - public void code(final Cache cache, final HTMLGen xgen) throws APIException, IOException { + public void code(final Cache cache, final HTMLGen htmlGen) throws APIException, IOException { // // TEMP // JSGen jsg = xgen.js(); // jsg.function("httpPost","sURL","sParam") @@ -53,25 +68,14 @@ public class Home extends Page { // .text(text) // jsg.done(); // TEMP - final Mark pages = xgen.divID("Pages"); - xgen.leaf(H3).text("Choose from the following:").end() - .leaf(A,"href=myperms").text("My Permissions").end() - .leaf(A,"href=myroles").text("My Roles").end() - // TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page - .leaf(A,"href=ns").text("My Namespaces").end() - .leaf(A,"href=approve").text("My Approvals").end() - .leaf(A, "href=myrequests").text("My Pending Requests").end() - // Enable later -// .leaf(A, "href=onboard").text("Onboarding").end() - // Password Change. If logged in as CSP/GSO, go to their page - .leaf(A,"href=passwd").text("Password Management").end() - .leaf(A,"href=cui").text("Command Prompt").end() - .leaf(A,"href=api").text("AAF API").end() - ; - - xgen.end(pages); + final Mark pages = htmlGen.divID("Pages"); + htmlGen.leaf(H3).text("Choose from the following:").end(); + for(String[] mi : MENU_ITEMS) { + htmlGen.leaf(A,"href="+mi[0]).text(mi[1]).end(); + } + htmlGen.end(pages); } }); } - + } diff --git a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/WebCommand.java b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/WebCommand.java index 6ad95e51..d0e834a5 100644 --- a/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/WebCommand.java +++ b/auth/auth-gui/src/main/java/org/onap/aaf/auth/gui/pages/WebCommand.java @@ -28,7 +28,9 @@ import org.onap.aaf.auth.gui.AAF_GUI; import org.onap.aaf.auth.gui.BreadCrumbs; import org.onap.aaf.auth.gui.NamedCode; import org.onap.aaf.auth.gui.Page; +import org.onap.aaf.auth.rserv.CachingFileAccess; import org.onap.aaf.misc.env.APIException; +import org.onap.aaf.misc.env.StaticSlot; import org.onap.aaf.misc.xgen.Cache; import org.onap.aaf.misc.xgen.DynamicCode; import org.onap.aaf.misc.xgen.Mark; @@ -41,6 +43,8 @@ public class WebCommand extends Page { super(gui.env, "Web Command Client",HREF, NO_FIELDS, new BreadCrumbs(breadcrumbs), new NamedCode(true, "content") { + StaticSlot sThemeWebPath = gui.env.staticSlot(CachingFileAccess.CFA_WEB_PATH); + StaticSlot sTheme = gui.env.staticSlot(AAF_GUI.AAF_GUI_THEME); @Override public void code(final Cache cache, final HTMLGen hgen) throws APIException, IOException { hgen.leaf("p","id=help_msg") @@ -56,31 +60,33 @@ public class WebCommand extends Page { hgen.end(); //console_area hgen.divID("options_link", "class=closed"); - hgen.img("src=../../"+gui.theme + "/options_down.png", "onclick=handleDivHiding('options',this);", - "id=options_img", "alt=Options", "title=Options") - .end(); //options_link - - hgen.divID("options"); cache.dynamic(hgen, new DynamicCode() { @Override public void code(AAF_GUI state, AuthzTrans trans, Cache cache, HTMLGen xgen) throws APIException, IOException { + String image_root = "src=../../"+state.env.get(sThemeWebPath).toString() + '/' + state.env.get(sTheme) + "/images/icons"; + hgen.img(image_root + "/options_down.png", "onclick=handleDivHiding('options',this);", + "id=options_img", "alt=Options", "title=Options") + .end(); //options_link + + hgen.divID("options"); + switch(browser(trans,trans.env().slot(getBrowserType()))) { case ie: case ieOld: // IE doesn't support file save break; default: - xgen.img("src=../../"+gui.theme+"/AAFdownload.png", "onclick=saveToFile();", + xgen.img(image_root+"/AAF_download.png", "onclick=saveToFile();", "alt=Save log to file", "title=Save log to file"); } -// xgen.img("src=../../"+gui.theme+"/AAFemail.png", "onclick=emailLog();", +// xgen.img("src=../../"+gui.theme+"/AAF_email.png", "onclick=emailLog();", // "alt=Email log to me", "title=Email log to me"); - xgen.img("src=../../"+gui.theme+"/AAF_font_size.png", "onclick=handleDivHiding('text_slider',this);", + xgen.img(image_root+"/AAF_font_size.png", "onclick=handleDivHiding('text_slider',this);", "id=fontsize_img", "alt=Change text size", "title=Change text size"); - xgen.img("src=../../"+gui.theme+"/AAF_details.png", "onclick=selectOption(this,0);", + xgen.img(image_root+"/AAF_details.png", "onclick=selectOption(this,0);", "id=details_img", "alt=Turn on/off details mode", "title=Turn on/off details mode"); - xgen.img("src=../../"+gui.theme+"/AAF_maximize.png", "onclick=maximizeConsole(this);", + xgen.img(image_root+"/AAF_maximize.png", "onclick=maximizeConsole(this);", "id=maximize_img", "alt=Maximize Console Window", "title=Maximize Console Window"); } }); diff --git a/auth/auth-gui/theme/onap/images/AAF_details.png b/auth/auth-gui/theme/onap/images/AAF_details.png new file mode 100644 index 0000000000000000000000000000000000000000..5c187459255b22df00373dda3f2b8ae0b2059575 GIT binary patch literal 650 zcmV;50(Jd~P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0v}04K~zXf<(Azm z!%-N=CodP0T!@lf;Kq%6S4#Na!PokWb#e?M?0 z8UGK^e{7`^wR%xM`baDBMPtyHD3VA3V=ctsGiF2jhyf7y>qk%J)B%**tie<1E!wJ? zL+H-=5{|(I5cdn4GqY_WyIlwMZd}Zs+;puOF#_dw=&VnkkPMN4l98R9cAe?L1(E!C zeSWM7%4pS=jT@o@cwT++b*la?lf~hNm;%U`&XODF{x-nw_9BzhN7qd3RBIi^M# z)e7)%mVB{daz7}bbaXGjdnH;x`NTfL?AbVnkPx#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&1eHldK~z{r-B(>q z990zlc6N8@!U_nKp9K_!B4|rODG$~*txaiDkyI;b)x`KvQxl)8Hq}-P^{1L>qA{jE z_+sS6#8ew2rqncTjWPOw6$3^aTjL)Tq=_x%Z)ay`{mz};%L2>NNV6s$GVGn1bMHC# zJKs6?j3-7Zefb1N$1V801~MUb)WPzgiQ$f|@RYpN6B`)|!}NPIVO!g#CO{Kj2pm{4hMG9eH?lIif5$>14?cVA{r$ z>u%LH9%Aeh^8BV+z;U2ZT0oZMfH2*g(Y|oEiEO6jBf8+AX);fTCJo8dwkP-oFDuRvGMc7zVLNO^cA@9FhN14DYseT@~c7a-$&1g31fx~*PM-n*Uzv!e4MB>DDl zm`T0PljnelgUAGPpAL7N;C)=)Y`YzpjHC>~tV$@PlFAi6+=`?9Lx>XkT@B^%Jar7d zEI*8RRTDiw$J5kP@DktdpN3(0JV?~NN$$9PRY)5xJN!9@ud?r$bNbFgz~Q8AwZ&@E zk*|M6SMQ%{+}?E4EC@yK-g;M0gm%$ZU#hC$J@G5qxahpNtCEl4&%R>1Z`bYp^YCuHv)$ZNGjvXIpG9D_+Ibt+JSd> zG{6bZ98d}Y@w6b@k4hGmfsrxcqE0z^7w{XXWlbMtj!!XEq1|Bh?=lMT4nCN={3q?!-0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&0p>|WK~z{r#h1HI z!!Q(vkJH;i*h;I;6+27Es7O>Gb>IQIbtghXER+p8m4Vk_r&4(hB;J9`1}wb>pWJZV zIJPS{JyRl``2WuD6DNmwH0t*+@bx=`V!?tuVzFF7b*~KXx2HgAcN6d9dkW=JArI|X zV>VwxZNCE6C#^hhail;^)V4~gwiC_`{@#pPs4duZk5h>5*Fjnx2i`jN#zdN3$AdLs z(6*u3K7@XVK#-A7%fM3r5U$}x zF{3gVCo-`iu_w|(p$QdLGt!7a93R;tfDNO|E=-3GJk-Q=TLg$iZE)QHWK>@V$pL@? zxu77uMuH-<3HfG9Gcv7tgXeGy9B`|_Qk3qvVa?i|$a100000NkvXXu0mjfZv*?B literal 0 HcmV?d00001 diff --git a/auth/auth-gui/theme/onap/images/AAFdownload.png b/auth/auth-gui/theme/onap/images/AAFdownload.png new file mode 100644 index 0000000000000000000000000000000000000000..cebd95223478bf7168c05b5b2162d926ae31d98e GIT binary patch literal 1834 zcmV+_2i5qAP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&2ER!}K~z{rwO4D1 zRaF%J_IcgMTpgX!e9f4Taq?A>rYWhQR7Cp2#0VsbAR>B685mLIk6uP3YCn2F)DNj2 zfuKeBt1u`S1yg!6=37V8nYlUldCoq&Z|!p@9i6MFxi9;kbI;j(t+m(s*0 zK792{6{k-W5yFAO|2>QqDBqr|(AMf>`Rp7f4@*PsIax5Te%^(S?+ehef#dw&%0=G! zBSl&xm-et^X%-t+v_h@ldCYA3=q$26?Q>mw{>0uJGsKj#4w1(GmJWl**!>ndKGLP(m`xF^WZs^fcE9l&)-q=R4355w~*V z5wrj2B78qd6R5$HkkLUkGMLkr#>0ym(Z_qo)Ycjo4LOb1KRttdq(NVz|J8+1mep1V zzbZWV>ZK#0R=j)C{N9I;-x0Lg-ZQ!FM+F%gN5WPVNUz$qbE%9(zSINiqY;sWU((R$Q%@#SOq5(a zT_(DY9mK})THgS^<{D-I*UFv&a^$ytCVF^fD6IEmEivOmKgr#M#l%v^lZ(aWxr~c> zZCT75pFwL=V!*(BNq)^3m&T0oDa@IYvN0ATtUU3Y;KKs622_fX1W*fKJYrIf0b+vD zScFHmda+7V3F|`aqR(i2@^mAnjmagdW3J^=B^20iO{{G(ld=7W65jaw6ozssGSQ1LH zPG>nAhWNl=Bf)1urq# zGeV^lq3@hVp%9V6`MVk-)Gk&o9!&$DJ!p=1hqYLY{o<&p2AY>G^xW4KkGG&G#pugyDk!RVKl`u3|zGzeu zmRew}Adeq8S+S^)r^UT_7N9Vs)egc61v6_FuI)s}p9PBn*|T}uX*{!~3qGnSmmHg3 zVHxNtRM1y&D2pT}*kS18Q`2bg>48J^K(9ru#IQ;*j>tK9@5u=$R;z5E(pdfW9~Q+- z9-b_Osk-Q{g!pOmG;|y|hsWPJj+>fgzY@67y)kCC=J4_(BT*_CdH`6x;Q)r_SjKCi zE3+0nxQHQ`%@7+>9XWite!_n;)O~v~wpsijIpCsP)eHe!GSPZI=ZR7Zy|^o!IW~=U=6735 z8k1TwXdjnF`^_0lY4I>)at`f$KBYB-$$U4tC5v0e11;7gG9)`h2b&pUK&Ehk?Vuzo zchUo=y9<_LB`rcy^O)f-cE2wk&`cR_w!k4au5xICRN7pLeXwjV#?iCl0XcQK3Oq2M z5NjQ-aEF z041XP*3mhrdtW+iA{HBAv{?H@tyDu9S8gn?J}`28s~){Y4|h-CpVO`1^_evvpTw-` z85SPaXO`a^IRs(76@_1ai?Qp?W+AZ9e6zcZFLo7CWeP}3bt4CB8JaU5o>-Q`?UQo& Y7c^3lExr!}S^xk507*qoM6N<$g5c0h;s5{u literal 0 HcmV?d00001 diff --git a/auth/auth-gui/theme/onap/images/AAFemail.png b/auth/auth-gui/theme/onap/images/AAFemail.png new file mode 100644 index 0000000000000000000000000000000000000000..6d48776998fe16cdbbfdaade33e9be89b8663901 GIT binary patch literal 2277 zcmVv00001b5ch_0Itp) z=>Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&2zp6GK~z{rtypc0 zTvZu<&dkp4%r&)$!@ z_uS_^@B2RQdyeyLy@PjRyfh7D+5out&pCKr>6{mcFT%CXQ|!sT@Y8|^jS+=+^^o4v zJv-+G|8(gi{SaTHRzsmXi{j4?!1ccW4qq(I0G(O5G(ond;8H|j-4KRj7~Jl?!RCqB z8!UnssJQzE??(-w!RvYreyW1Lo*WTuKIGArhwEsE%cR-c;8Q%drDLFCF#)FYgv}-u z%K$7e36qH#3|K@KdDMBm4qqqGYR$T*g`L}ayGLgZ$Yqgg&%hI8N@hS8B4&5MS;_?(J*kHz?^{2RN*V^d06y`#g< z!E-yd^m- zKGo9+m(OxQ0pY{^sN;hI?PzNAQL$*&ZZ$bAQf;8n*^Uovd=vIoxgqw zPyY2RUOqR8_8dX92AMG#Gb%rHX66PW28)x4)u(3=vAfb#01F1qPM|b##PM8}CN_}Mh{{z1 zNd&Q9*sLt-)I)q2d!f&PQRnR2IhnZt|8jP6){~EYY!lXATtHR9(At_-Nh~CClfV+D z_&QcQIjcaLP)JV#EF);mt$8z!ZN^+V^)|1_v4Enx!U~m2hX2r{4S&7`OkE5-F@+S8&3y}m8VY*0P zWCS9j>^Mmedo;xiSRBPQyY|D~blm&e$SM5v8}|S!R={;L(j^g+3(0~aUAk#N>B7uP z9DW|iXHJb_c&f^Tbv`3mc4MTcd2jo-evgbMtf-brldNI@712Q#rHu?0jEvwtd-fu; zat++zcf4QSPa?a4`@eh?(<7t6%8QWh>V#)tq@-s8O8xR}8Kej{A{%x2*s=3W-tns! zap2p3018YD!bxe8Ip6X2OK|dqv&c{d%;01(B706Im0Jm15bmf<_J&81BU!iXzZD}T z;MHOBvTo;Xw@JpNq1$(C#=x4j`17+TY-UzuG_wTtQXHxnkj3aj6=Hes`c-D~Etjpp zws)?^Q~xOksbv zIBx#v4JZ}?CL5GlRv450^y@<2+!0+}B!KVV{`n)8s@%%Hm`!B{3cayPvqkjL2H6}x zx&uABzewBiwWsj(-^nJ;-efQ2=7=c#$e7X|4u0iJv=lH-ysRxSE@CI*f@@Zr;g5VC zM~)rDyS8nC|JP|WCZ?D}r)}1#Xy#;@*#Ts~K*{;dKWUQ%+I_!$2~R)&3euF7*sOei zn#>VJW4r|a@+n+(?PeUlj{x~yeSdD7$E0E;1TpfRz_~Le96NH%rsMj0;c^VBX0FX3 z;>gi70h7(W*T2mQ8A))KL3Y;@e=;9TXZSKpFGf)eR3M9_h}U}$?Zd#uU6^95sMe6? zSNLcvlM8}OW}{r6rz_ll?{WP5#7STvNL4Vua=aqnz}A!|LgN=x)JAEabXTbkGc`o? zKSjfuD>vd(dv~E+HWjiae}7#d^|Asb%b-2+%nNw*!AF4Z98y85Or}hlXnXldQn4#z zktt(PfnwT6M5E*Q&?k1|%1u{bhCbJtgmkV~IF}1BSpZlFK{Y^P?hCn?iX^GX(80S= zo}jrTRb

7*wq26F+hMnlgz|B!Ke6(IWEQ-8eAxSsR*3ZeD8zSt8*RA#h@I3nWdN zCy2#BCaf|!;m1!rho2vR%x0JB=ZrpJ-Mn`6|*NSvO zknbbNfn|V92F(%IE6mpqe*Gboi(_y-%m!9}vUs*in*hgHOBTAZ=aaYK(lveNe~Yzw zAo=_-$S$`RZ?%jv} zf&UG#`MnE(aAMNTtz{0)%}i)Zo8`3b9^fA@4&%v3e~414#30LKaOVx!u<;U1(sh^G zWB?^31aKe=c?4xuM6bdcbj92MU5!a2X@6KH%9Q2-N1hVbXU`AAlV`O00000NkvXXu0mjf0s392 literal 0 HcmV?d00001 diff --git a/auth/auth-gui/theme/onap/images/LF_Collab_footer_gray.png b/auth/auth-gui/theme/onap/images/LF_Collab_footer_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..abbf4b1a0910e1465995f2ec4689a5ad8aafc8e8 GIT binary patch literal 47307 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 literal 0 HcmV?d00001 diff --git a/auth/auth-gui/theme/onap/images/LF_Collab_header_gray.png b/auth/auth-gui/theme/onap/images/LF_Collab_header_gray.png new file mode 100644 index 0000000000000000000000000000000000000000..43781fad95932ca2989a58916e5db945e2a345fb GIT binary patch literal 21018 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

We6BCTF}h;}Jf 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 u02ogM { - private static final String DOT_OAUTH = ".oauth"; public Map cacheUser; public AAFAuthn aafAuthn; public AAFLurPerm aafLurPerm; @@ -103,7 +102,8 @@ public class AAF_OAuth extends AbsService { // Start Background Processing // Question question = - question = new Question(trans, cluster, CassAccess.KEYSPACE, true); + question = new Question(trans, cluster, CassAccess.KEYSPACE); + question.startTimers(env); // Have AAFLocator object Create DirectLocators for Location needs AbsAAFLocator.setCreator(new DirectLocatorCreator(env, question.locateDAO)); diff --git a/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java b/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java index e3aed80c..1e4b6cbb 100644 --- a/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java +++ b/auth/auth-oauth/src/main/java/org/onap/aaf/auth/oauth/service/OAuthService.java @@ -76,7 +76,7 @@ public class OAuthService { @SuppressWarnings("unchecked") public OAuthService(final Access access, final AuthzTrans trans, final Question q) throws APIException, IOException { permLoader = JSONPermLoaderFactory.direct(q); - tokenDAO = new OAuthTokenDAO(trans, q.historyDAO); + tokenDAO = new OAuthTokenDAO(trans, q.historyDAO()); daos =(DAO[]) new DAO[] { tokenDAO }; diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AAF_Service.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AAF_Service.java index 90d4744a..6a63907d 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AAF_Service.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AAF_Service.java @@ -25,6 +25,7 @@ import javax.servlet.Filter; import org.onap.aaf.auth.cache.Cache; import org.onap.aaf.auth.dao.CassAccess; +import org.onap.aaf.auth.dao.cass.CacheInfoDAO; import org.onap.aaf.auth.dao.hl.Question; import org.onap.aaf.auth.direct.DirectAAFLur; import org.onap.aaf.auth.direct.DirectAAFUserPass; @@ -96,8 +97,10 @@ public class AAF_Service extends AbsService { // Need Question for Security purposes (direct User/Authz Query in Filter) // Start Background Processing - question = new Question(trans, cluster, CassAccess.KEYSPACE, true); - DirectCertIdentity.set(question.certDAO); + question = new Question(trans, cluster, CassAccess.KEYSPACE); + question.startTimers(env); + + DirectCertIdentity.set(question.certDAO()); // Have AAFLocator object Create DirectLocators for Location needs AbsAAFLocator.setCreator(new DirectLocatorCreator(env, question.locateDAO)); @@ -190,10 +193,20 @@ public class AAF_Service extends AbsService { new DirectRegistrar(access,question.locateDAO, actualPort) }; } + + @Override + public void postStartup(final String hostname, final int port) throws APIException { + try { + CacheInfoDAO.startUpdate(env, aafCon().hman(), aafCon().securityInfo().defSS,hostname,port); + } catch (CadiException | LocatorException e) { + throw new APIException(e); + } + } @Override public void destroy() { Cache.stopTimer(); + CacheInfoDAO.stopUpdate(); if (cluster!=null) { cluster.close(); } diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java index 81a9d5ec..751825c1 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/AuthzCassServiceImpl.java @@ -168,6 +168,7 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -318,7 +319,8 @@ public class AuthzCassServiceImpl > rsd = ques.nsDAO.dao().readNsByAttrib(trans, key); + Result> rsd = ques.nsDAO().dao().readNsByAttrib(trans, key); if (rsd.notOK()) { return Result.err(rsd); } @@ -382,7 +384,7 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -401,8 +403,8 @@ public class AuthzCassServiceImpl > rlnsd = ques.nsDAO.read(trans, ns); + Result> rlnsd = ques.nsDAO().read(trans, ns); if (rlnsd.notOKorIsEmpty()) { return Result.err(rlnsd); } @@ -451,7 +453,8 @@ public class AuthzCassServiceImpl > rlnd = ques.nsDAO.read(trans, ns); + Result> rlnd = ques.nsDAO().read(trans, ns); if (rlnd.isOK()) { if (rlnd.isEmpty()) { return Result.err(Status.ERR_NotFound, "No data found for %s",ns); @@ -563,7 +565,7 @@ public class AuthzCassServiceImpl > loadNamepace(AuthzTrans trans, String user, String endsWith, boolean full) { - Result> urd = ques.userRoleDAO.readByUser(trans, user); + Result> urd = ques.userRoleDAO().readByUser(trans, user); if (urd.notOKorIsEmpty()) { return Result.err(urd); } @@ -679,7 +681,7 @@ public class AuthzCassServiceImpl lm = new HashSet<>(); - Result> rlnd = ques.nsDAO.dao().getChildren(trans, parent); + Result> rlnd = ques.nsDAO().dao().getChildren(trans, parent); if (rlnd.isOK()) { if (rlnd.isEmpty()) { return Result.err(Status.ERR_NotFound, "No data found for %s",parent); @@ -727,7 +729,7 @@ public class AuthzCassServiceImpl > rlnd = ques.nsDAO.read(trans, namespace.name); + Result> rlnd = ques.nsDAO().read(trans, namespace.name); if (rlnd.notOKorIsEmpty()) { return Result.err(Status.ERR_NotFound, "Namespace [%s] does not exist",namespace.name); @@ -737,7 +739,7 @@ public class AuthzCassServiceImpl rdr = ques.nsDAO.dao().addDescription(trans, namespace.name, namespace.description); + Result rdr = ques.nsDAO().dao().addDescription(trans, namespace.name, namespace.description); if (rdr.isOK()) { return Result.ok(); } else { @@ -797,6 +799,12 @@ public class AuthzCassServiceImpl createPerm(final AuthzTrans trans,REQUEST rreq) { final Result newPd = mapper.perm(trans, rreq); + // Does Perm Type exist as a Namespace? + if(newPd.value.type.isEmpty() || ques.nsDAO().read(trans, newPd.value.fullType()).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Permission Type exists as a Namespace"); + } + final ServiceValidator v = new ServiceValidator(); if (v.perm(newPd).err()) { return Result.err(Status.ERR_BadData,v.errs()); @@ -822,7 +830,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, newPd.value.ns); + Result> nsr = ques.nsDAO().read(trans, newPd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1138,7 +1146,7 @@ public class AuthzCassServiceImpl > rlpd = ques.permDAO.readNS(trans, ns); + Result> rlpd = ques.permDAO().readNS(trans, ns); if (rlpd.notOK()) { return Result.err(rlpd); } @@ -1176,7 +1184,7 @@ public class AuthzCassServiceImpl nss = ques.deriveNsSplit(trans, origType); - Result> origRlpd = ques.permDAO.read(trans, nss.value.ns, nss.value.name, origInstance, origAction); + Result> origRlpd = ques.permDAO().read(trans, nss.value.ns, nss.value.name, origInstance, origAction); if (origRlpd.notOKorIsEmpty()) { return Result.err(Status.ERR_PermissionNotFound, @@ -1235,7 +1243,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, pd.value.ns); + Result> nsr = ques.nsDAO().read(trans, pd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } - Result rdr = ques.permDAO.addDescription(trans, perm.ns, perm.type, perm.instance, + Result rdr = ques.permDAO().addDescription(trans, perm.ns, perm.type, perm.instance, perm.action, perm.description); if (rdr.isOK()) { return Result.ok(); @@ -1287,7 +1295,7 @@ public class AuthzCassServiceImpl > rcurr = ques.permDAO.read(trans, + Result> rcurr = ques.permDAO().read(trans, updt.value.ns, updt.value.type, updt.value.instance, @@ -1321,7 +1329,7 @@ public class AuthzCassServiceImpl key = RoleDAO.Data.decode(trans, ques, role); if (key.isOKhasData()) { - Result> rrd = ques.roleDAO.read(trans, key.value); + Result> rrd = ques.roleDAO().read(trans, key.value); if (rrd.isOKhasData()) { for (RoleDAO.Data r : rrd.value) { rv = func.addPermToRole(trans, r, curr, false); @@ -1341,7 +1349,7 @@ public class AuthzCassServiceImpl key = RoleDAO.Data.decode(trans, ques, role); if (key.isOKhasData()) { - Result> rdd = ques.roleDAO.read(trans, key.value); + Result> rdd = ques.roleDAO().read(trans, key.value); if (rdd.isOKhasData()) { for (RoleDAO.Data r : rdd.value) { rv = func.delPermFromRole(trans, r, curr, true); @@ -1380,7 +1388,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, perm.ns); + Result> nsr = ques.nsDAO().read(trans, perm.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1483,12 +1491,17 @@ public class AuthzCassServiceImpl createRole(final AuthzTrans trans, REQUEST from) { final Result rd = mapper.role(trans, from); + // Does Perm Type exist as a Namespace? + if(rd.value.name.isEmpty() || ques.nsDAO().read(trans, rd.value.fullName()).isOKhasData()) { + return Result.err(Status.ERR_ConflictAlreadyExists, + "Role exists as a Namespace"); + } final ServiceValidator v = new ServiceValidator(); if (v.role(rd).err()) { return Result.err(Status.ERR_BadData,v.errs()); } final RoleDAO.Data role = rd.value; - if (ques.roleDAO.read(trans, role.ns, role.name).isOKhasData()) { + if (ques.roleDAO().read(trans, role.ns, role.name).isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "Role [" + role.fullName() + "] already exists"); } @@ -1512,7 +1525,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1529,7 +1542,7 @@ public class AuthzCassServiceImpl rdr = ques.roleDAO.create(trans, role); + Result rdr = ques.roleDAO().create(trans, role); if (rdr.isOK()) { return Result.ok(); } else { @@ -1608,10 +1621,10 @@ public class AuthzCassServiceImpl > rlrd; - Result> rlurd = ques.userRoleDAO.readByUser(trans, user); + Result> rlurd = ques.userRoleDAO().readByUser(trans, user); if (rlurd.isOKhasData()) { for (UserRoleDAO.Data urd : rlurd.value ) { - rlrd = ques.roleDAO.read(trans, urd.ns,urd.rname); + rlrd = ques.roleDAO().read(trans, urd.ns,urd.rname); // Note: Mapper will restrict what can be viewed // if user is the same as that which is looked up, no filtering is required if (rlrd.isOKhasData()) { @@ -1658,7 +1671,7 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.readNS(trans, ns); + Result> rlrd = ques.roleDAO().readNS(trans, ns); if (rlrd.isOK()) { if (!rlrd.isEmpty()) { // Note: Mapper doesn't need to restrict what can be viewed, because we did it already. @@ -1700,7 +1713,7 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.readName(trans, name); + Result> rlrd = ques.roleDAO().readName(trans, name); if (rlrd.isOK()) { if (!rlrd.isEmpty()) { // Note: Mapper will restrict what can be viewed @@ -1757,13 +1770,13 @@ public class AuthzCassServiceImpl > pdlr = ques.permDAO.read(trans, pdd); + Result> pdlr = ques.permDAO().read(trans, pdd); if (pdlr.isOK())for (PermDAO.Data pd : pdlr.value) { Result> rlrd; for (String r : pd.roles) { Result rs = RoleDAO.Data.decodeToArray(trans, ques, r); if (rs.isOK()) { - rlrd = ques.roleDAO.read(trans, rs.value[0],rs.value[1]); + rlrd = ques.roleDAO().read(trans, rs.value[0],rs.value[1]); // Note: Mapper will restrict what can be viewed if (rlrd.isOKhasData()) { mapper.roles(trans,rlrd.value,roles,true); @@ -1799,7 +1812,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } - Result rdr = ques.roleDAO.addDescription(trans, role.ns, role.name, role.description); + Result rdr = ques.roleDAO().addDescription(trans, role.ns, role.name, role.description); if (rdr.isOK()) { return Result.ok(); } else { @@ -1861,13 +1874,13 @@ public class AuthzCassServiceImpl > rlrd = ques.roleDAO.read(trans, rrd.value.ns, rrd.value.name); + Result> rlrd = ques.roleDAO().read(trans, rrd.value.ns, rrd.value.name); if (rlrd.notOKorIsEmpty()) { return Result.err(Status.ERR_RoleNotFound, "Role [%s] does not exist", rrd.value.fullName()); } // Check Status of Data in DB (does it exist) - Result> rlpd = ques.permDAO.read(trans, rpd.value.ns, + Result> rlpd = ques.permDAO().read(trans, rpd.value.ns, rpd.value.type, rpd.value.instance, rpd.value.action); PermDAO.Data createPerm = null; // if not null, create first if (rlpd.notOKorIsEmpty()) { // Permission doesn't exist @@ -1908,7 +1921,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rpd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rpd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -1980,7 +1993,7 @@ public class AuthzCassServiceImpl delPermFromRole(final AuthzTrans trans, PermDAO.Data pdd, RoleDAO.Data rdd, REQUEST rreq) { - Result> rlpd = ques.permDAO.read(trans, pdd.ns, pdd.type, + Result> rlpd = ques.permDAO().read(trans, pdd.ns, pdd.type, pdd.instance, pdd.action); if (rlpd.notOKorIsEmpty()) { @@ -2007,7 +2020,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, pdd.ns); + Result> nsr = ques.nsDAO().read(trans, pdd.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2070,12 +2083,12 @@ public class AuthzCassServiceImpl > rrd = ques.roleDAO.read(trans, rrns.value.parent, rrns.value.name); + final Result> rrd = ques.roleDAO().read(trans, rrns.value.parent, rrns.value.name); if (rrd.notOKorIsEmpty()) { return Result.err(rrd); } - final Result> rpd = ques.permDAO.read(trans, rpns.value.parent, rpns.value.name, instance, action); + final Result> rpd = ques.permDAO().read(trans, rpns.value.parent, rpns.value.name, instance, action); if (rpd.notOKorIsEmpty()) { return Result.err(rpd); } @@ -2131,7 +2144,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rd.value.ns); + Result> nsr = ques.nsDAO().read(trans, rd.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2299,7 +2312,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rcred.value.ns); + Result> nsr = ques.nsDAO().read(trans, rcred.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(Status.ERR_NsNotFound,"Cannot provision %s on non-existent Namespace %s",mechID.id(),rcred.value.ns); } @@ -2309,7 +2322,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, rcred.value.id); + Result> rlcd = ques.credDAO().readID(trans, rcred.value.id); if (rlcd.isOKhasData()) { if (!org.canHaveMultipleCreds(rcred.value.id)) { return Result.err(Status.ERR_ConflictAlreadyExists, "Credential exists"); @@ -2335,7 +2348,7 @@ public class AuthzCassServiceImpl udr = ques.credDAO.create(trans, rcred.value); + Resultudr = ques.credDAO().create(trans, rcred.value); if (udr.isOK()) { return Result.ok(); } @@ -2442,7 +2455,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readNS(trans, ns); + Result> rlcd = ques.credDAO().readNS(trans, ns); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2489,7 +2502,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, id); + Result> rlcd = ques.credDAO().readID(trans, id); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2519,7 +2532,7 @@ public class AuthzCassServiceImpl > rlcd = ques.certDAO.readID(trans, id); + Result> rlcd = ques.certDAO().readID(trans, id); if (rlcd.isOK()) { if (!rlcd.isEmpty()) { @@ -2560,7 +2573,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, rcred.value.id); + Result> rlcd = ques.credDAO().readID(trans, rcred.value.id); if (rlcd.notOKorIsEmpty()) { return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } @@ -2592,7 +2605,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, rcred.value.ns); + Result> nsr = ques.nsDAO().read(trans, rcred.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2634,9 +2647,9 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, cred.value.id); + Result> rlcd = ques.credDAO().readID(trans, cred.value.id); if (rlcd.notOKorIsEmpty()) { return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); } @@ -2735,7 +2748,7 @@ public class AuthzCassServiceImpl > rlcd = ques.credDAO.readID(trans, cred.value.id); + Result> rlcd = ques.credDAO().readID(trans, cred.value.id); if (rlcd.notOKorIsEmpty()) { // Empty Creds should have no user_roles. - Result> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id); + Result> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO.delete(trans, data, false); + ques.userRoleDAO().delete(trans, data, false); } } return Result.err(Status.ERR_UserNotFound, "Credential does not exist"); @@ -2859,7 +2872,7 @@ public class AuthzCassServiceImpl > nsr = ques.nsDAO.read(trans, cred.value.ns); + Result> nsr = ques.nsDAO().read(trans, cred.value.ns); if (nsr.notOKorIsEmpty()) { return Result.err(nsr); } @@ -2880,20 +2893,20 @@ public class AuthzCassServiceImpl = rlcd.value.size()) { return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id); } - udr = ques.credDAO.delete(trans, rlcd.value.get(entry),false); + udr = ques.credDAO().delete(trans, rlcd.value.get(entry),false); } else { for (CredDAO.Data curr : rlcd.value) { - udr = ques.credDAO.delete(trans, curr, false); + udr = ques.credDAO().delete(trans, curr, false); if (udr.notOK()) { return Result.err(udr); } } } if (isLastCred) { - Result> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id); + Result> rlurd = ques.userRoleDAO().readByUser(trans, cred.value.id); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { - ques.userRoleDAO.delete(trans, data, false); + ques.userRoleDAO().delete(trans, data, false); } } } @@ -3094,7 +3107,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, role); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { userSet.add(data); @@ -3127,7 +3140,7 @@ public class AuthzCassServiceImpl > rlurd = ques.userRoleDAO.readByUser(trans, user); + Result> rlurd = ques.userRoleDAO().readByUser(trans, user); if (rlurd.notOK()) { return Result.err(rlurd); } @@ -3188,172 +3201,9 @@ public class AuthzCassServiceImpl resetRolesForUser(AuthzTrans trans, REQUEST rreq) { - Result rurdd = mapper.userRole(trans, rreq); - final ServiceValidator v = new ServiceValidator(); - if (rurdd.notOKorIsEmpty()) { - return Result.err(rurdd); - } - if (v.user(trans.org(), rurdd.value.user).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - Set currRoles = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByUser(trans, rurdd.value.user); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - currRoles.add(data.role); - } - } - - Result rv = null; - String[] roles; - if (rurdd.value.role==null) { - roles = new String[0]; - } else { - roles = rurdd.value.role.split(","); - } - - for (String role : roles) { - if (v.role(role).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - Result rrdd = RoleDAO.Data.decode(trans, ques, role); - if (rrdd.notOK()) { - return Result.err(rrdd); - } - - rurdd.value.role(rrdd.value); - - Result nsd = ques.mayUser(trans, trans.user(), rrdd.value,Access.write); - if (nsd.notOK()) { - return Result.err(nsd); - } - Result nsr = ques.deriveNs(trans, role); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - if (currRoles.contains(role)) { - currRoles.remove(role); - } else { - rv = func.addUserRole(trans, rurdd.value); - if (rv.notOK()) { - return rv; - } - } - } - - for (String role : currRoles) { - rurdd.value.role(trans,ques,role); - rv = ques.userRoleDAO.delete(trans, rurdd.value, false); - if (rv.notOK()) { - trans.info().log(rurdd.value.user,"/",rurdd.value.role, "expected to be deleted, but does not exist"); - // return rv; // if it doesn't exist, don't error out - } - - } - - return Result.ok(); - - } - - @ApiDoc( - method = PUT, - path = "/authz/userRole/role", - params = {}, - expectedCode = 200, - errorCodes = {403,404,406}, - text = { "Set a Role's users to the users specified in the UserRoleRequest object.", - "WARNING: Users supplied will be the ONLY users attached to this role", - "If no users are supplied, role's users are reset." - } - ) - @Override - public Result resetUsersForRole(AuthzTrans trans, REQUEST rreq) { - Result rurdd = mapper.userRole(trans, rreq); - if (rurdd.notOKorIsEmpty()) { - return Result.err(rurdd); - } - final ServiceValidator v = new ServiceValidator(); - if (v.user_role(rurdd.value).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - - RoleDAO.Data rd = RoleDAO.Data.decode(rurdd.value); - - Result nsd = ques.mayUser(trans, trans.user(), rd, Access.write); - if (nsd.notOK()) { - return Result.err(nsd); - } - - Result nsr = ques.deriveNs(trans, rurdd.value.role); - if (nsr.notOKorIsEmpty()) { - return Result.err(nsr); - } - - Set currUsers = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, rurdd.value.role); - if (rlurd.isOK()) { - for (UserRoleDAO.Data data : rlurd.value) { - currUsers.add(data.user); - } - } - - // found when connected remotely to DEVL, can't replicate locally - // inconsistent errors with cmd: role user setTo [nothing] - // deleteUserRole --> read --> get --> cacheIdx(?) - // sometimes returns idx for last added user instead of user passed in - // cache bug? - - - Result rv = null; - String[] users = {}; - if (rurdd.value.user != null) { - users = rurdd.value.user.split(","); - } - - for (String user : users) { - if (v.user(trans.org(), user).err()) { - return Result.err(Status.ERR_BadData,v.errs()); - } - rurdd.value.user = user; - - if (currUsers.contains(user)) { - currUsers.remove(user); - } else { - rv = func.addUserRole(trans, rurdd.value); - if (rv.notOK()) { - return rv; - } - } - } - - for (String user : currUsers) { - rurdd.value.user = user; - rv = ques.userRoleDAO.delete(trans, rurdd.value, false); - if (rv.notOK()) { - trans.info().log(rurdd.value, "expected to be deleted, but not exists"); - return rv; - } - } - - return Result.ok(); - } + - @ApiDoc( + @ApiDoc( method = GET, path = "/authz/userRole/extend/:user/:role", params = { "user|string|true", @@ -3386,7 +3236,7 @@ public class AuthzCassServiceImpl > rr = ques.userRoleDAO.read(trans, user,role); + Result> rr = ques.userRoleDAO().read(trans, user,role); if (rr.notOK()) { return Result.err(rr); } @@ -3461,7 +3311,7 @@ public class AuthzCassServiceImpl > rulr; - if ((rulr=ques.userRoleDAO.read(trans, usr, role)).notOKorIsEmpty()) { + if ((rulr=ques.userRoleDAO().read(trans, usr, role)).notOKorIsEmpty()) { return Result.err(Status.ERR_UserRoleNotFound, "User [ "+usr+" ] is not " + "Assigned to the Role [ " + role + " ]"); } @@ -3485,7 +3335,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readUserInRole(trans, user, role); + Result> rlurd = ques.userRoleDAO().readUserInRole(trans, user, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { userSet.add(data); @@ -3573,7 +3423,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); - Result> rlurd = ques.userRoleDAO.readByRole(trans, role); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role); if (rlurd.isOK()) { for (UserRoleDAO.Data data : rlurd.value) { if (contactOnly) { //scrub data @@ -3626,7 +3476,7 @@ public class AuthzCassServiceImpl > nsd = ques.nsDAO.read(trans, nss.value.ns); + Result> nsd = ques.nsDAO().read(trans, nss.value.ns); if (nsd.notOK()) { return Result.err(nsd); } @@ -3640,7 +3490,7 @@ public class AuthzCassServiceImpl userSet = new HashSet<>(); if (!nss.isEmpty()) { - Result> rlp = ques.permDAO.readByType(trans, nss.value.ns, nss.value.name); + Result> rlp = ques.permDAO().readByType(trans, nss.value.ns, nss.value.name); if (rlp.isOKhasData()) { for (PermDAO.Data pd : rlp.value) { if ((allInstance || pd.instance.equals(instance)) && @@ -3649,7 +3499,7 @@ public class AuthzCassServiceImpl > rlurd = ques.userRoleDAO.readByRole(trans, role.replace('|', '.')); + Result> rlurd = ques.userRoleDAO().readByRole(trans, role.replace('|', '.')); if (rlurd.isOKhasData()) { for (UserRoleDAO.Data urd : rlurd.value) { userSet.add(urd); @@ -3703,7 +3553,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readByUser(trans, user, yyyymm); + Result> resp = ques.historyDAO().readByUser(trans, user, yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3726,7 +3576,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readBySubject(trans, role, "role", yyyymm); + Result> resp = ques.historyDAO().readBySubject(trans, role, "role", yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3751,7 +3601,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readBySubject(trans, type, "perm", yyyymm); + Result> resp = ques.historyDAO().readBySubject(trans, type, "perm", yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3775,7 +3625,7 @@ public class AuthzCassServiceImpl > resp = ques.historyDAO.readBySubject(trans, ns, "ns", yyyymm); + Result> resp = ques.historyDAO().readBySubject(trans, ns, "ns", yyyymm); if (resp.notOK()) { return Result.err(resp); } @@ -3805,7 +3655,7 @@ public class AuthzCassServiceImpl > ddr = ques.delegateDAO.read(trans, dd); + Result> ddr = ques.delegateDAO().read(trans, dd); if (access==Access.create && ddr.isOKhasData()) { return Result.err(Status.ERR_ConflictAlreadyExists, "[%s] already delegates to [%s]", dd.user, ddr.value.get(0).delegate); } else if (access!=Access.create && ddr.notOKorIsEmpty()) { @@ -3845,14 +3695,14 @@ public class AuthzCassServiceImpl rdr = ques.delegateDAO.create(trans, dd); + Result rdr = ques.delegateDAO().create(trans, dd); if (rdr.isOK()) { return Result.ok(); } else { return Result.err(rdr); } } else { - return ques.delegateDAO.update(trans, dd); + return ques.delegateDAO().update(trans, dd); } default: return Result.err(fd); @@ -3868,7 +3718,7 @@ public class AuthzCassServiceImpl > ddl; - if ((ddl=ques.delegateDAO.read(trans, rd.value)).notOKorIsEmpty()) { + if ((ddl=ques.delegateDAO().read(trans, rd.value)).notOKorIsEmpty()) { return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate"); } final DelegateDAO.Data dd = ddl.value.get(0); @@ -3877,7 +3727,7 @@ public class AuthzCassServiceImpl > ddl; - if ((ddl=ques.delegateDAO.read(trans, dd)).notOKorIsEmpty()) { + if ((ddl=ques.delegateDAO().read(trans, dd)).notOKorIsEmpty()) { return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate"); } dd = ddl.value.get(0); @@ -3898,7 +3748,7 @@ public class AuthzCassServiceImpl > dbDelgs = ques.delegateDAO.read(trans, user); + Result> dbDelgs = ques.delegateDAO().read(trans, user); try { if (dbDelgs.isOKhasData()) { return mapper.delegate(dbDelgs.value); @@ -3946,7 +3796,7 @@ public class AuthzCassServiceImpl > dbDelgs = ques.delegateDAO.readByDelegate(trans, delegate); + Result> dbDelgs = ques.delegateDAO().readByDelegate(trans, delegate); try { if (dbDelgs.isOKhasData()) { return mapper.delegate(dbDelgs.value); @@ -3979,16 +3829,16 @@ public class AuthzCassServiceImpl > apprByTicket=null; for (ApprovalDAO.Data updt : rlad.value) { if (updt.ticket!=null) { - curr = ques.approvalDAO.readByTicket(trans, updt.ticket); + curr = ques.approvalDAO().readByTicket(trans, updt.ticket); if (curr.isOKhasData()) { final List add = curr.value; // Store a Pre-Lookup apprByTicket = (trans1, noop) -> add; } } else if (updt.id!=null) { - curr = ques.approvalDAO.read(trans, updt); + curr = ques.approvalDAO().read(trans, updt); } else if (updt.approver!=null) { - curr = ques.approvalDAO.readByApprover(trans, updt.approver); + curr = ques.approvalDAO().readByApprover(trans, updt.approver); } else { return Result.err(Status.ERR_BadData,"Approvals need ID, Ticket or Approval data to update"); } @@ -4024,7 +3874,7 @@ public class AuthzCassServiceImpl rfdd = ques.futureDAO.readPrimKey(trans, cd.ticket); + Result rfdd = ques.futureDAO().readPrimKey(trans, cd.ticket); if (rfdd.isOK()) { fdd = rfdd.value; // null is ok } else { @@ -4067,7 +3917,7 @@ public class AuthzCassServiceImpl > rapd = ques.approvalDAO.readByUser(trans, user); + Result> rapd = ques.approvalDAO().readByUser(trans, user); if (rapd.isOK()) { return mapper.approvals(rapd.value); } else { @@ -4131,7 +3981,7 @@ public class AuthzCassServiceImpl > rapd = ques.approvalDAO.readByTicket(trans, uuid); + Result> rapd = ques.approvalDAO().readByTicket(trans, uuid); if (rapd.isOK()) { return mapper.approvals(rapd.value); } else { @@ -4148,19 +3998,19 @@ public class AuthzCassServiceImpl listRapds = new ArrayList<>(); - Result> myRapd = ques.approvalDAO.readByApprover(trans, approver); + Result> myRapd = ques.approvalDAO().readByApprover(trans, approver); if (myRapd.notOK()) { return Result.err(myRapd); } listRapds.addAll(myRapd.value); - Result> delegatedFor = ques.delegateDAO.readByDelegate(trans, approver); + Result> delegatedFor = ques.delegateDAO().readByDelegate(trans, approver); if (delegatedFor.isOK()) { for (DelegateDAO.Data dd : delegatedFor.value) { if (dd.expires.after(new Date())) { String delegator = dd.user; - Result> rapd = ques.approvalDAO.readByApprover(trans, delegator); + Result> rapd = ques.approvalDAO().readByApprover(trans, delegator); if (rapd.isOK()) { for (ApprovalDAO.Data d : rapd.value) { if (!d.user.equals(trans.user())) { @@ -4210,7 +4060,7 @@ public class AuthzCassServiceImpl getUserRolesByUser(AuthzTrans trans, String user); - /** - * - * @param trans - * @param from - * @return - */ - public Result resetRolesForUser(AuthzTrans trans, REQUEST from); - - /** - * - * @param trans - * @param from - * @return + /* + * Note: Removed "resetRolesForUsers" because it was too dangerous, and + * removed "resetUsersForRoles" because it was being misused. */ - public Result resetUsersForRole(AuthzTrans trans, REQUEST from); /** * diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_Creds.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_Creds.java index 7a028c91..c8bae9f0 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_Creds.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_Creds.java @@ -112,7 +112,6 @@ public class API_Creds { decoded.substring(0,colon), CredVal.Type.PASSWORD , decoded.substring(colon+1).getBytes(),trans)) { - resp.setStatus(HttpStatus.OK_200); } else { // DME2 at this version crashes without some sort of response diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_UserRole.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_UserRole.java index 7937a184..a56b7c26 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_UserRole.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/api/API_UserRole.java @@ -104,21 +104,17 @@ public class API_UserRole { } }); - + /* TODO + * REMOVE dangerous resetUsersForRole and resetRolesForUser APIs + */ + final Result removeAPI = Result.err(Result.ERR_NotFound,"API Removed, use /authz/userRole instead."); /** * Update roles attached to user in path */ authzAPI.route(PUT,"/authz/userRole/user",API.USER_ROLE_REQ,new Code(facade,"Update Roles for a user", true) { @Override public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { - Result r = context.resetRolesForUser(trans, resp, req); - switch(r.status) { - case OK: - resp.setStatus(HttpStatus.OK_200); - break; - default: - context.error(trans,resp,r); - } + context.error(trans,resp,removeAPI); } }); @@ -129,16 +125,14 @@ public class API_UserRole { authzAPI.route(PUT,"/authz/userRole/role",API.USER_ROLE_REQ,new Code(facade,"Update Users for a role", true) { @Override public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception { - Result r = context.resetUsersForRole(trans, resp, req); - switch(r.status) { - case OK: - resp.setStatus(HttpStatus.OK_200); - break; - default: - context.error(trans,resp,r); - } + context.error(trans,resp,removeAPI); } }); + + /* + * END REMOVE Dangerous API + */ + /** * Extend Expiration Date (according to Organizational rules) diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java index a08e958f..463de35f 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacade.java @@ -210,10 +210,10 @@ public interface AuthzFacade { public abstract Result getUserRolesByUser(AuthzTrans trans, HttpServletResponse resp, String user); public abstract Result deleteUserRole(AuthzTrans trans, HttpServletResponse resp, String user, String role); - - public abstract Result resetUsersForRole(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req); - public abstract Result resetRolesForUser(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req); + /* + * resetUsersForRoles and resetRolesForUsers is too dangerous and not helpful. + */ public abstract Result extendUserRoleExpiration(AuthzTrans trans, HttpServletResponse resp, String user, String role); diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java index a2fb2209..02fa842f 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/facade/AuthzFacadeImpl.java @@ -66,9 +66,9 @@ import org.onap.aaf.auth.service.mapper.Mapper.API; import org.onap.aaf.cadi.aaf.client.Examples; import org.onap.aaf.misc.env.APIException; import org.onap.aaf.misc.env.Data; +import org.onap.aaf.misc.env.Data.TYPE; import org.onap.aaf.misc.env.Env; import org.onap.aaf.misc.env.TimeTaken; -import org.onap.aaf.misc.env.Data.TYPE; import org.onap.aaf.misc.env.util.Chrono; import org.onap.aaf.misc.rosetta.Marshal; import org.onap.aaf.misc.rosetta.env.RosettaDF; @@ -1939,8 +1939,8 @@ public abstract class AuthzFacadeImpl resetUsersForRole(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req) { - TimeTaken tt = trans.start(SET_USERS_FOR_ROLE, Env.SUB|Env.ALWAYS); - try { - REQUEST rreq; - try { - RosettaData data = userRoleRequestDF.newData().load(req.getInputStream()); - if (Question.willSpecialLog(trans, trans.user())) { - Question.logEncryptTrace(trans,data.asString()); - } - rreq = data.asObject(); - } catch (APIException e) { - trans.error().log("Invalid Input",IN, SET_USERS_FOR_ROLE); - return Result.err(Status.ERR_BadData,"Invalid Input"); - } - - Result rp = service.resetUsersForRole(trans, rreq); - - switch(rp.status) { - case OK: - setContentType(resp,permsDF.getOutType()); - return Result.ok(); - default: - return Result.err(rp); - } - } catch (Exception e) { - trans.error().log(e,IN,SET_USERS_FOR_ROLE); - return Result.err(e); - } finally { - tt.done(); - } - - } - - @Override - public Result resetRolesForUser(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req) { - TimeTaken tt = trans.start(SET_ROLES_FOR_USER, Env.SUB|Env.ALWAYS); - try { - REQUEST rreq; - try { - RosettaData data = userRoleRequestDF.newData().load(req.getInputStream()); - if (Question.willSpecialLog(trans, trans.user())) { - Question.logEncryptTrace(trans,data.asString()); - } - - rreq = data.asObject(); - } catch (APIException e) { - trans.error().log("Invalid Input",IN, SET_ROLES_FOR_USER); - return Result.err(Status.ERR_BadData,"Invalid Input"); - } - - Result rp = service.resetRolesForUser(trans, rreq); - - switch(rp.status) { - case OK: - setContentType(resp,permsDF.getOutType()); - return Result.ok(); - default: - return Result.err(rp); - } - } catch (Exception e) { - trans.error().log(e,IN,SET_ROLES_FOR_USER); - return Result.err(e); - } finally { - tt.done(); - } - - } - /* (non-Javadoc) * @see com.att.authz.facade.AuthzFacade#extendUserRoleExpiration(org.onap.aaf.auth.env.test.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String) */ diff --git a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java index 2d322390..72a24d21 100644 --- a/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java +++ b/auth/auth-service/src/main/java/org/onap/aaf/auth/service/mapper/Mapper_2_0.java @@ -541,6 +541,7 @@ public class Mapper_2_0 implements Mapper { erroringTimer = null; } } else { + env.error().log(rv.toString()); // Account for different Registrations not being to same place if (erroringTimer==null) { erroringTimer = new Timer(REGISTRAR + " error re-check ",true); diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java index ac715163..5221d8ea 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/register/RegistrationCreator.java @@ -98,15 +98,25 @@ public class RegistrationCreator { String protocol = access.getProperty(Config.AAF_LOCATOR_PROTOCOL + dot_le, null); if (protocol!=null) { locate.setProtocol(protocol); - String subprotocols = access.getProperty(Config.AAF_LOCATOR_SUBPROTOCOL + dot_le, null); - if(subprotocols!=null) { - List ls = locate.getSubprotocol(); - for (String s : Split.split(',', subprotocols)) { - ls.add(s); - } - } + List ls = locate.getSubprotocol(); + if(ls==null || ls.isEmpty()) { + String subprotocols = access.getProperty(Config.AAF_LOCATOR_SUBPROTOCOL + dot_le, null); + if(subprotocols==null) { + subprotocols = access.getProperty(Config.CADI_PROTOCOLS, null); + } + if(subprotocols!=null) { + for (String s : Split.split(',', subprotocols)) { + ls.add(s); + } + } else { + access.printf(Level.ERROR, "%s is required for Locator Registration of %s", + Config.AAF_LOCATOR_SUBPROTOCOL,Config.AAF_LOCATOR_PROTOCOL); + } + } + lme.add(locate); + } else { + access.printf(Level.ERROR, "%s is required for Locator Registration",Config.AAF_LOCATOR_PROTOCOL); } - lme.add(locate); } } } catch (NumberFormatException | UnknownHostException e) { diff --git a/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java b/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java index c9b8b4ee..7c589ae3 100644 --- a/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java +++ b/cadi/aaf/src/main/java/org/onap/aaf/cadi/sso/AAFSSO.java @@ -319,7 +319,7 @@ public class AAFSSO { if(aaf_root_ns==null) { locateRoot=Defaults.AAF_ROOT; } else { - locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS.%" + aaf_root_ns; + locateRoot = Defaults.AAF_LOCATE_CONST + "/%CNS." + aaf_root_ns; } if(access.getProperty(Config.AAF_URL)==null) { diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java index 2fe5f41c..d6b8d56d 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/PropAccess.java @@ -28,6 +28,7 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; +import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -149,6 +150,7 @@ public class PropAccess implements Access { name = props.getProperty(Config.CADI_LOGNAME, name); SecurityInfo.setHTTPProtocols(this); + } @@ -260,27 +262,34 @@ public class PropAccess implements Access { return buildMsg(name,iso8601,level,elements); } - public static StringBuilder buildMsg(final String name, final SimpleDateFormat sdf, Level level, Object[] elements) { - StringBuilder sb = new StringBuilder(sdf.format(new Date())); - sb.append(' '); - sb.append(level.name()); - sb.append(" ["); - sb.append(name); - + public static StringBuilder buildMsg(final String name, final DateFormat sdf, Level level, Object[] elements) { + final StringBuilder sb; int end = elements.length; - if (end<=0) { - sb.append("] "); - } else { - int idx = 0; - if(elements[idx]!=null && - elements[idx] instanceof Integer) { - sb.append('-'); - sb.append(elements[idx]); - ++idx; - } - sb.append("] "); - write(true,sb,elements); - } + if(sdf==null) { + sb = new StringBuilder(); + write(true,sb,elements); + } else { + sb = new StringBuilder( + sdf.format(new Date()) + ); + sb.append(' '); + sb.append(level.name()); + sb.append(" ["); + sb.append(name); + if (end<=0) { + sb.append("] "); + } else { + int idx = 0; + if(elements[idx]!=null && + elements[idx] instanceof Integer) { + sb.append('-'); + sb.append(elements[idx]); + ++idx; + } + sb.append("] "); + write(true,sb,elements); + } + } return sb; } diff --git a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java index ff1f3955..8cb1045b 100644 --- a/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java +++ b/cadi/core/src/main/java/org/onap/aaf/cadi/config/Config.java @@ -88,6 +88,9 @@ public class Config { public static final String CADI_LOGDIR = "cadi_log_dir"; public static final String CADI_ETCDIR = "cadi_etc_dir"; public static final String CADI_LOGNAME = "cadi_logname"; +// public static final String CADI_LOGFMT="cad_logging_format"; +// public static final String CADI_LOGFMT_UTC="UTC"; +// public static final String CADI_LOGFMT_ISO8601="ISO-8601"; public static final String CADI_KEYFILE = "cadi_keyfile"; public static final String CADI_KEYSTORE = "cadi_keystore"; public static final String CADI_KEYSTORE_PASSWORD = "cadi_keystore_password"; @@ -174,6 +177,11 @@ public class Config { public static final String AAF_LOCATOR_PUBLIC_PORT = "aaf_locator_public_port"; public static final String AAF_LOCATOR_PUBLIC_FQDN = "aaf_locator_public_fqdn"; public static final String AAF_LOCATOR_PUBLIC_NAME = "aaf_locator_public_name"; + + // AAF Service will write to the Audit Log if a past due AAF stored Password + // is being used within # of days specified. + public static final String AAF_CRED_WARN_DAYS="aaf_cred_warn_days"; + public static final String AAF_CRED_WARN_DAYS_DFT="7"; public static final String AAF_APPID = "aaf_id"; public static final String AAF_APPPASS = "aaf_password"; diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java b/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java index a1a81b9d..58c588f6 100644 --- a/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java +++ b/misc/env/src/main/java/org/onap/aaf/misc/env/TimeTaken.java @@ -77,8 +77,8 @@ public abstract class TimeTaken { end = System.nanoTime(); } - - /** + + /** * For sizable contents, set the size. Implementations can simply write a no-op if they don't wish to * store the size. * diff --git a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java index 83a049c1..5ba74369 100644 --- a/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java +++ b/misc/env/src/main/java/org/onap/aaf/misc/env/impl/AbsTrans.java @@ -112,7 +112,6 @@ public abstract class AbsTrans implements TransStore { public final void checkpoint(String name, int additionalFlag) { TimeTaken tt = newTimeTaken(name,CHECKPOINT|additionalFlag); trail.add(tt); - tt.done(); } @Override @@ -130,8 +129,13 @@ public abstract class AbsTrans implements TransStore { // If first entry is sub, then it's actually the last "end" as well // otherwise, check end //long end = (first.flag&SUB)==SUB?first.end():trail.get(last).end(); - long end = trail.get(last).end(); + long end = 0L; + for(int i=last;end==0L && i>=0;--i) { + end= trail.get(i).end(); + } metric.total = (end - first.start) / 1000000f; + } else { + metric.total=0L; } if (sb==null) { @@ -165,6 +169,18 @@ public abstract class AbsTrans implements TransStore { for (int i=0;i implements TransStore { ++indent; } - // Add time values to Metric - float ms = tt.millis(); - for (int i=0;i(); js = new ArrayList<>(); this.backdots = backdots; -- 2.16.6