summaryrefslogtreecommitdiffstats
path: root/auth/auth-batch/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'auth/auth-batch/src/main')
-rw-r--r--auth/auth-batch/src/main/config/.gitignore2
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/Batch.java524
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchException.java51
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchPrincipal.java41
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/CassBatch.java78
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Action.java29
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionDAO.java73
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionPuntDAO.java72
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CacheTouch.java53
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredDelete.java55
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPrint.java56
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPunt.java70
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Email.java220
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/EmailPrint.java98
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/FuturePrint.java41
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Key.java26
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Message.java53
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSACreate.java58
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSADelete.java58
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSDescUpdate.java58
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermCreate.java69
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermDelete.java64
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermModify.java141
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleCreate.java66
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleDelete.java62
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleModify.java152
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URAdd.java57
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URDelete.java59
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApprove.java111
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java108
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFuturePrint.java41
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URModify.java80
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPrint.java42
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPunt.java70
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/AafEntryConverter.java46
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/CredEntryConverter.java48
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/NsEntryConverter.java46
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/PermEntryConverter.java43
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/RoleEntryConverter.java42
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/UserRoleEntryConverter.java45
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approval.java309
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approver.java62
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/CacheChange.java63
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Creator.java41
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Cred.java306
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Future.java200
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/History.java178
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/InputIterator.java69
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Loader.java26
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MiscID.java188
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MonthData.java121
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NS.java168
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Notification.java209
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NsAttrib.java107
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Perm.java172
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Role.java175
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java282
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java143
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java503
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/update/ExpiringP2.java158
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyApprovals.java236
-rw-r--r--auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java321
62 files changed, 7145 insertions, 0 deletions
diff --git a/auth/auth-batch/src/main/config/.gitignore b/auth/auth-batch/src/main/config/.gitignore
new file mode 100644
index 00000000..28a74e22
--- /dev/null
+++ b/auth/auth-batch/src/main/config/.gitignore
@@ -0,0 +1,2 @@
+/authBatch.props
+/log4j.properties
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/Batch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/Batch.java
new file mode 100644
index 00000000..6d9252e2
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/Batch.java
@@ -0,0 +1,524 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.lang.reflect.Constructor;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
+import java.text.SimpleDateFormat;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.apache.log4j.Logger;
+import org.onap.aaf.auth.common.Define;
+import org.onap.aaf.auth.dao.CassAccess;
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.auth.org.Organization.Identity;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.StaticSlot;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.impl.Log4JLogTarget;
+import org.onap.aaf.misc.env.log4j.LogFileNamer;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.Statement;
+
+public abstract class Batch {
+
+ private static String ROOT_NS;
+
+ private static StaticSlot ssargs;
+
+ protected static final String STARS = "*****";
+
+ protected final Cluster cluster;
+ protected static AuthzEnv env;
+ protected static Session session;
+ protected static Logger aspr;
+ protected static Set<String> specialNames;
+ protected static boolean dryRun;
+ protected static String batchEnv;
+
+ public static final String CASS_ENV = "CASS_ENV";
+ public static final String LOG_DIR = "LOG_DIR";
+ protected final static String PUNT="punt";
+ protected final static String MAX_EMAILS="MAX_EMAILS";
+ protected final static String VERSION="VERSION";
+ public final static String GUI_URL="GUI_URL";
+
+ protected final static String ORA_URL="ora_url";
+ protected final static String ORA_PASSWORD="ora_password";
+ protected final Organization org;
+
+
+
+ protected Batch(AuthzEnv env) throws APIException, IOException, OrganizationException {
+ // Be able to change Environments
+ // load extra properties, i.e.
+ // PERF.cassandra.clusters=....
+ batchEnv = env.getProperty(CASS_ENV);
+ if(batchEnv != null) {
+ batchEnv = batchEnv.trim();
+ env.info().log("Redirecting to ",batchEnv,"environment");
+ String str;
+ for(String key : new String[]{
+ CassAccess.CASSANDRA_CLUSTERS,
+ CassAccess.CASSANDRA_CLUSTERS_PORT,
+ CassAccess.CASSANDRA_CLUSTERS_USER_NAME,
+ CassAccess.CASSANDRA_CLUSTERS_PASSWORD,
+ VERSION,GUI_URL,PUNT,MAX_EMAILS,
+ LOG_DIR,
+ "SPECIAL_NAMES"
+ }) {
+ if((str = env.getProperty(batchEnv+'.'+key))!=null) {
+ env.setProperty(key, str);
+ }
+ }
+ }
+
+ // Setup for Dry Run
+ cluster = CassAccess.cluster(env,batchEnv);
+ env.info().log("cluster name - ",cluster.getClusterName());
+ String dryRunStr = env.getProperty( "DRY_RUN" );
+ if ( dryRunStr == null || dryRunStr.trim().equals("false") ) {
+ dryRun = false;
+ } else {
+ dryRun = true;
+ env.info().log("dryRun set to TRUE");
+ }
+
+ org = OrganizationFactory.init(env);
+ org.setTestMode(dryRun);
+
+ // Special names to allow behaviors beyond normal rules
+ specialNames = new HashSet<String>();
+ String names = env.getProperty( "SPECIAL_NAMES" );
+ if ( names != null )
+ {
+ env.info().log("Loading SPECIAL_NAMES");
+ for (String s :names.split(",") )
+ {
+ env.info().log("\tspecial: " + s );
+ specialNames.add( s.trim() );
+ }
+ }
+ }
+
+ protected abstract void run(AuthzTrans trans);
+ protected abstract void _close(AuthzTrans trans);
+
+ public String[] args() {
+ return (String[])env.get(ssargs);
+ }
+
+ public boolean isDryRun()
+ {
+ return dryRun;
+ }
+
+ public boolean isSpecial(String user) {
+ if (specialNames != null && specialNames.contains(user)) {
+ env.info().log("specialName: " + user);
+
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ public boolean isMechID(String user) {
+ if (user.matches("m[0-9][0-9][0-9][0-9][0-9]")) {
+ return (true);
+ } else {
+ return (false);
+ }
+ }
+
+ protected PrintStream fallout(PrintStream _fallout, String logType)
+ throws IOException {
+ PrintStream fallout = _fallout;
+ if (fallout == null) {
+ File dir = new File("logs");
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+
+ File f = null;
+ // String os = System.getProperty("os.name").toLowerCase();
+ long uniq = System.currentTimeMillis();
+
+ f = new File(dir, getClass().getSimpleName() + "_" + logType + "_"
+ + uniq + ".log");
+
+ fallout = new PrintStream(new FileOutputStream(f, true));
+ }
+ return fallout;
+ }
+
+ public Organization getOrgFromID(AuthzTrans trans, String user) {
+ Organization org;
+ try {
+ org = OrganizationFactory.obtain(trans.env(),user.toLowerCase());
+ } catch (OrganizationException e1) {
+ trans.error().log(e1);
+ org=null;
+ }
+
+ if (org == null) {
+ PrintStream fallout = null;
+
+ try {
+ fallout = fallout(fallout, "Fallout");
+ fallout.print("INVALID_ID,");
+ fallout.println(user);
+ } catch (Exception e) {
+ env.error().log("Could not write to Fallout File", e);
+ }
+ return (null);
+ }
+
+ return (org);
+ }
+
+ public static Row executeDeleteQuery(Statement stmt) {
+ Row row = null;
+ if (!dryRun) {
+ row = session.execute(stmt).one();
+ }
+
+ return (row);
+
+ }
+
+ public static int acquireRunLock(String className) {
+ Boolean testEnv = true;
+ String envStr = env.getProperty("AFT_ENVIRONMENT");
+
+ if (envStr != null) {
+ if (envStr.equals("AFTPRD")) {
+ testEnv = false;
+ }
+ } else {
+ env.fatal()
+ .log("AFT_ENVIRONMENT property is required and was not found. Exiting.");
+ System.exit(1);
+ }
+
+ if (testEnv) {
+ env.info().log("TESTMODE: skipping RunLock");
+ return (1);
+ }
+
+ String hostname = null;
+ try {
+ hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ e.printStackTrace();
+ env.warn().log("Unable to get hostname");
+ return (0);
+ }
+
+ ResultSet existing = session.execute(String.format(
+ "select * from authz.run_lock where class = '%s'", className));
+
+ for (Row row : existing) {
+ long curr = System.currentTimeMillis();
+ ByteBuffer lastRun = row.getBytesUnsafe(2); // Can I get this field
+ // by name?
+
+ long interval = (1 * 60 * 1000); // @@ Create a value in props file
+ // for this
+ long prev = lastRun.getLong();
+
+ if ((curr - prev) <= interval) {
+ env.warn().log(
+ String.format("Too soon! Last run was %d minutes ago.",
+ ((curr - prev) / 1000) / 60));
+ env.warn().log(
+ String.format("Min time between runs is %d minutes ",
+ (interval / 1000) / 60));
+ env.warn().log(
+ String.format("Last ran on machine: %s at %s",
+ row.getString("host"), row.getDate("start")));
+ return (0);
+ } else {
+ env.info().log("Delete old lock");
+ deleteLock(className);
+ }
+ }
+
+ GregorianCalendar current = new GregorianCalendar();
+
+ // We want our time in UTC, hence "+0000"
+ SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss+0000");
+ fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+ String cql = String
+ .format("INSERT INTO authz.run_lock (class,host,start) VALUES ('%s','%s','%s') IF NOT EXISTS",
+ className, hostname, fmt.format(current.getTime()));
+
+ env.info().log(cql);
+
+ Row row = session.execute(cql).one();
+ if (!row.getBool("[applied]")) {
+ env.warn().log("Lightweight Transaction failed to write lock.");
+ env.warn().log(
+ String.format("host with lock: %s, running at %s",
+ row.getString("host"), row.getDate("start")));
+ return (0);
+ }
+ return (1);
+ }
+
+ private static void deleteLock( String className) {
+ Row row = session.execute( String.format( "DELETE FROM authz.run_lock WHERE class = '%s' IF EXISTS", className ) ).one();
+ if (! row.getBool("[applied]")) {
+ env.info().log( "delete failed" );
+ }
+ }
+
+ private static void transferVMProps(AuthzEnv env, String ... props) {
+ String value;
+ for(String key : props) {
+ if((value = System.getProperty(key))!=null) {
+ env.setProperty(key, value);
+ }
+ }
+ }
+
+ // IMPORTANT! VALIDATE Organization isUser method
+ protected void checkOrganizationAcccess(AuthzTrans trans, Question q) throws APIException, OrganizationException {
+ Set<String> testUsers = new HashSet<String>();
+ Result<List<RoleDAO.Data>> rrd = q.roleDAO.readNS(trans, ROOT_NS);
+ if(rrd.isOK()) {
+ for(RoleDAO.Data r : rrd.value) {
+ Result<List<UserRoleDAO.Data>> rur = q.userRoleDAO.readByRole(trans, r.fullName());
+ if(rur.isOK()) {
+ for(UserRoleDAO.Data udd : rur.value) {
+ testUsers.add(udd.user);
+ }
+ }
+ }
+ }
+ if(testUsers.size()<2) {
+ throw new APIException("Not enough Users in Roles for " + ROOT_NS + " to Validate");
+ }
+
+ Identity iden;
+ for(String user : testUsers) {
+ if((iden=org.getIdentity(trans,user))==null) {
+ throw new APIException("Failed Organization Entity Validation Check: " + user);
+ } else {
+ trans.info().log("Organization Validation Check: " + iden.id());
+ }
+ }
+ }
+
+ protected static String logDir() {
+ String ld = env.getProperty(LOG_DIR);
+ if(ld==null) {
+ if(batchEnv==null) { // Deployed Batch doesn't use different ENVs, and a common logdir
+ ld = "logs/";
+ } else {
+ ld = "logs/"+batchEnv;
+ }
+ }
+ return ld;
+ }
+ protected int count(String str, char c) {
+ int count=str==null||str.isEmpty()?0:1;
+ for(int i=str.indexOf(c);i>=0;i=str.indexOf(c,i+1)) {
+ ++count;
+ }
+ return count;
+ }
+
+ public final void close(AuthzTrans trans) {
+ _close(trans);
+ cluster.close();
+ }
+
+ public static void main(String[] args) {
+ PropAccess access = new PropAccess(args);
+ InputStream is = null;
+ String filename;
+ String propLoc;
+ try {
+ Define.set(access);
+ ROOT_NS=Define.ROOT_NS();
+
+ File f = new File("etc/authzBatch.props");
+ try {
+ if (f.exists()) {
+ filename = f.getAbsolutePath();
+ is = new FileInputStream(f);
+ propLoc = f.getPath();
+ } else {
+ URL rsrc = ClassLoader.getSystemResource("authBatch.props");
+ filename = rsrc.toString();
+ is = rsrc.openStream();
+ propLoc = rsrc.getPath();
+ }
+ access.load(is);
+ } finally {
+ if (is == null) {
+ System.err.println("authBatch.props must exist in etc dir, or in Classpath");
+ System.exit(1);
+ }
+ is.close();
+ }
+
+ env = new AuthzEnv(access);
+
+ transferVMProps(env, CASS_ENV, "DRY_RUN", "NS", "Organization");
+
+ // Flow all Env Logs to Log4j, with ENV
+
+ LogFileNamer lfn;
+ if ((batchEnv = env.getProperty(CASS_ENV)) == null) {
+ lfn = new LogFileNamer(logDir()).noPID();
+ } else {
+ lfn = new LogFileNamer(logDir()).noPID();
+ }
+
+ lfn.setAppender("authz-batch");
+ lfn.setAppender("aspr|ASPR");
+ lfn.setAppender("sync");
+ lfn.setAppender("jobchange");
+ lfn.setAppender("validateuser");
+ aspr = Logger.getLogger("aspr");
+ Log4JLogTarget.setLog4JEnv("authz-batch", env);
+ if (filename != null) {
+ env.init().log("Instantiated properties from", filename);
+ }
+
+ // Log where Config found
+ env.info().log("Configuring from", propLoc);
+ propLoc = null;
+
+ Batch batch = null;
+ // setup ATTUser and Organization Slots before starting this:
+ // TODO redo this
+ // env.slot(ATT.ATT_USERSLOT);
+ //
+ // OrganizationFactory.setDefaultOrg(env, ATT.class.getName());
+ AuthzTrans trans = env.newTrans();
+
+ TimeTaken tt = trans.start("Total Run", Env.SUB);
+ try {
+ int len = args.length;
+ if (len > 0) {
+ String toolName = args[0];
+ len -= 1;
+ if (len < 0)
+ len = 0;
+ String nargs[] = new String[len];
+ if (len > 0) {
+ System.arraycopy(args, 1, nargs, 0, len);
+ }
+
+ env.put(ssargs = env.staticSlot("ARGS"), nargs);
+
+ /*
+ * Add New Batch Programs (inherit from Batch) here
+ */
+
+ // Might be a Report, Update or Temp Batch
+ Class<?> cls;
+ String classifier = "";
+ try {
+ cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.update." + toolName);
+ classifier = "Update:";
+ } catch (ClassNotFoundException e) {
+ try {
+ cls = ClassLoader.getSystemClassLoader().loadClass("org.onap.aaf.auth.reports." + toolName);
+ classifier = "Report:";
+ } catch (ClassNotFoundException e2) {
+ try {
+ cls = ClassLoader.getSystemClassLoader()
+ .loadClass("org.onap.aaf.auth.temp." + toolName);
+ classifier = "Temp Utility:";
+ } catch (ClassNotFoundException e3) {
+ cls = null;
+ }
+ }
+ }
+ if (cls != null) {
+ Constructor<?> cnst = cls.getConstructor(new Class[] { AuthzTrans.class });
+ batch = (Batch) cnst.newInstance(trans);
+ env.info().log("Begin", classifier, toolName);
+ }
+
+
+ if (batch == null) {
+ trans.error().log("No Batch named", toolName, "found");
+ }
+ /*
+ * End New Batch Programs (inherit from Batch) here
+ */
+
+ }
+ if (batch != null) {
+ batch.run(trans);
+ }
+ } finally {
+ tt.done();
+ if (batch != null) {
+ batch.close(trans);
+ }
+ StringBuilder sb = new StringBuilder("Task Times\n");
+ trans.auditTrail(4, sb, AuthzTrans.SUB, AuthzTrans.REMOTE);
+ trans.info().log(sb);
+ }
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ // Exceptions thrown by DB aren't stopping the whole process.
+ System.exit(1);
+ }
+ }
+
+}
+
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchException.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchException.java
new file mode 100644
index 00000000..4ed0940a
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchException.java
@@ -0,0 +1,51 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth;
+
+public class BatchException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -3877245367723491192L;
+
+ public BatchException() {
+ }
+
+ public BatchException(String message) {
+ super(message);
+ }
+
+ public BatchException(Throwable cause) {
+ super(cause);
+ }
+
+ public BatchException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public BatchException(String message, Throwable cause,
+ boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchPrincipal.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchPrincipal.java
new file mode 100644
index 00000000..6ca79018
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/BatchPrincipal.java
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth;
+
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+
+public class BatchPrincipal extends TaggedPrincipal {
+ private final String name;
+
+ public BatchPrincipal(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String tag() {
+ return "Batch";
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/CassBatch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/CassBatch.java
new file mode 100644
index 00000000..32e8f85d
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/CassBatch.java
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.org.OrganizationException;
+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.impl.Log4JLogTarget;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.exceptions.InvalidQueryException;
+
+public abstract class CassBatch extends Batch {
+
+ protected CassBatch(AuthzTrans trans, String log4JName) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+ // Flow all Env Logs to Log4j
+ Log4JLogTarget.setLog4JEnv(log4JName, env);
+
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ trans.info().log("Closed Session");
+ }
+
+ public ResultSet executeQuery(String cql) {
+ return executeQuery(cql,"");
+ }
+
+ public ResultSet executeQuery(String cql, String extra) {
+ if(isDryRun() && !cql.startsWith("SELECT")) {
+ if(extra!=null)env.info().log("Would query" + extra + ": " + cql);
+ } else {
+ if(extra!=null)env.info().log("query" + extra + ": " + cql);
+ try {
+ return session.execute(cql);
+ } catch (InvalidQueryException e) {
+ if(extra==null) {
+ env.info().log("query: " + cql);
+ }
+ throw e;
+ }
+ }
+ return null;
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Action.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Action.java
new file mode 100644
index 00000000..ad3a447d
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Action.java
@@ -0,0 +1,29 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+
+public interface Action<D,RV,T> {
+ public Result<RV> exec(AuthzTrans trans, D data, T t);
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionDAO.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionDAO.java
new file mode 100644
index 00000000..90400015
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionDAO.java
@@ -0,0 +1,73 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.CassAccess;
+import org.onap.aaf.auth.dao.hl.Function;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public abstract class ActionDAO<D,RV,T> implements Action<D,RV,T> {
+ protected final Question q;
+ protected final Function f;
+ private boolean clean;
+ protected final boolean dryRun;
+
+ public ActionDAO(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ q = new Question(trans, cluster, CassAccess.KEYSPACE, false);
+ f = new Function(trans,q);
+ clean = true;
+ this.dryRun = dryRun;
+ }
+
+ public ActionDAO(AuthzTrans trans, ActionDAO<?,?,?> predecessor) {
+ q = predecessor.q;
+ f = new Function(trans,q);
+ clean = false;
+ dryRun = predecessor.dryRun;
+ }
+
+ public Session getSession(AuthzTrans trans) throws APIException, IOException {
+ return q.historyDAO.getSession(trans);
+ }
+
+ public Question question() {
+ return q;
+ }
+
+ public Function function() {
+ return f;
+ }
+
+ public void close(AuthzTrans trans) {
+ if(clean) {
+ q.close(trans);
+ }
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionPuntDAO.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionPuntDAO.java
new file mode 100644
index 00000000..332d2509
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/ActionPuntDAO.java
@@ -0,0 +1,72 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public abstract class ActionPuntDAO<D, RV, T> extends ActionDAO<D, RV, T> {
+// private static final SecureRandom random = new SecureRandom();
+ private int months;
+// private int range;
+ protected static final Date now = new Date();
+
+ public ActionPuntDAO(AuthzTrans trans, Cluster cluster, int months, int range, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ this.months = months;
+// this.range = range;
+ }
+
+ public ActionPuntDAO(AuthzTrans trans, ActionDAO<?, ?,?> predecessor, int months, int range) {
+ super(trans, predecessor);
+ this.months = months;
+// this.range = range;
+ }
+
+
+ protected Date puntDate(Date current) {
+ GregorianCalendar temp = new GregorianCalendar();
+ temp.setTime(current);
+ temp.add(GregorianCalendar.MONTH, months);
+
+ /*
+ * This method Randomized date. This is no longer needed. Just add the Punt Months.
+ temp.setTime(now);
+ temp.add(GregorianCalendar.MONTH, months);
+ if(range>0) {
+ int forward = Math.abs(random.nextInt()%range);
+ if(forward>1) {
+ temp.add(GregorianCalendar.MONTH, forward);
+ temp.add(GregorianCalendar.DAY_OF_MONTH, (random.nextInt()%30)-15);
+ }
+ }
+ */
+ return temp.getTime();
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CacheTouch.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CacheTouch.java
new file mode 100644
index 00000000..8261c477
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CacheTouch.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class CacheTouch extends ActionDAO<String,Void, String> {
+
+ public CacheTouch(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public CacheTouch(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, String table, String text) {
+ if(dryRun) {
+ trans.info().printf("Would mark %s cache in DB for clearing: %s",table, text);
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.clearCache(trans, table);
+ trans.info().printf("Set DB Cache %s for clearing: %s",table, text);
+ return rv;
+ }
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredDelete.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredDelete.java
new file mode 100644
index 00000000..700aaaea
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredDelete.java
@@ -0,0 +1,55 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class CredDelete extends ActionDAO<CredDAO.Data,Void, String> {
+
+ public CredDelete(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public CredDelete(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred, String text) {
+ if(dryRun) {
+ trans.info().log("Would Delete:",text,cred.id,CredPrint.type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.credDAO.delete(trans, cred, true); // need to read for undelete
+ trans.info().log("Deleted:",text,cred.id,CredPrint.type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+ return rv;
+ }
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPrint.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPrint.java
new file mode 100644
index 00000000..10407ce4
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPrint.java
@@ -0,0 +1,56 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class CredPrint implements Action<CredDAO.Data,Void,String> {
+ private String info;
+
+ public CredPrint(String text) {
+ this.info = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred, String text) {
+ trans.info().log(info,cred.id,text, type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+ return Result.ok();
+ }
+
+
+ public static String type(int type) {
+ switch(type) {
+ case CredDAO.BASIC_AUTH: // 1
+ return "OLD";
+ case CredDAO.BASIC_AUTH_SHA256: // 2
+ return "U/P";
+ case CredDAO.CERT_SHA256_RSA: // 200
+ return "Cert";
+ default:
+ return "Unknown";
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPunt.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPunt.java
new file mode 100644
index 00000000..78c1f892
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/CredPunt.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class CredPunt extends ActionPuntDAO<CredDAO.Data,Void,String> {
+
+ public CredPunt(AuthzTrans trans, Cluster cluster, int months, int range, boolean dryRun) throws IOException, APIException {
+ super(trans,cluster,months,range,dryRun);
+ }
+
+ public CredPunt(AuthzTrans trans, ActionDAO<?,?,?> adao, int months, int range) throws IOException {
+ super(trans, adao, months,range);
+ }
+
+ public Result<Void> exec(AuthzTrans trans, CredDAO.Data cdd,String text) {
+ Result<Void> rv = null;
+ Result<List<CredDAO.Data>> read = q.credDAO.read(trans, cdd);
+ if(read.isOKhasData()) {
+ for(CredDAO.Data data : read.value) {
+ Date from = data.expires;
+ data.expires = puntDate(from);
+ if(data.expires.compareTo(from)<=0) {
+ trans.debug().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+ } else {
+ if(dryRun) {
+ trans.info().log("Would Update Cred",cdd.id, CredPrint.type(cdd.type), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+ } else {
+ trans.info().log("Updated Cred",cdd.id, CredPrint.type(cdd.type), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+ rv = q.credDAO.update(trans, data);
+ }
+ }
+ }
+ }
+ if(rv==null) {
+ rv=Result.err(read);
+ }
+ return rv;
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Email.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Email.java
new file mode 100644
index 00000000..346e517f
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Email.java
@@ -0,0 +1,220 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.Organization.Identity;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class Email implements Action<Organization,Void, String>{
+ protected final List<String> toList;
+ protected final List<String> ccList;
+ private final String[] defaultCC;
+ protected String subject;
+ private String preamble;
+ private Message msg;
+ private String sig;
+ protected String lineIndent=" ";
+ private long lastSent=0L;
+
+
+ public Email(String ... defaultCC) {
+ toList = new ArrayList<String>();
+ this.defaultCC = defaultCC;
+ ccList = new ArrayList<String>();
+ clear();
+ }
+
+ public Email clear() {
+ toList.clear();
+ ccList.clear();
+ for(String s: defaultCC) {
+ ccList.add(s);
+ }
+ return this;
+ }
+
+
+ public void indent(String indent) {
+ lineIndent = indent;
+ }
+
+ public void preamble(String format, Object ... args) {
+ preamble = String.format(format, args);
+ }
+
+ public Email addTo(Identity id) {
+ if(id!=null) {
+ if(!toList.contains(id.email())) {
+ toList.add(id.email());
+ }
+ }
+ return this;
+ }
+
+ public Email addTo(Collection<String> users) {
+ for(String u : users) {
+ addTo(u);
+ }
+ return this;
+ }
+
+ public Email addTo(String email) {
+ if(!toList.contains(email)) {
+ toList.add(email);
+ }
+ return this;
+ }
+
+ public Email addCC(Identity id) {
+ if(id!=null) {
+ if(!ccList.contains(id.email())) {
+ ccList.add(id.email());
+ }
+ }
+ return this;
+ }
+
+ public Email addCC(String email) {
+ if(!ccList.contains(email)) {
+ ccList.add(email);
+ }
+ return this;
+ }
+
+
+ public Email add(Identity id, boolean toSuper) throws OrganizationException {
+ Identity responsible = id.responsibleTo();
+ if(toSuper) {
+ addTo(responsible.email());
+ addCC(id.email());
+ } else {
+ addCC(responsible.email());
+ addTo(id.email());
+ }
+ return this;
+ }
+
+ public Email subject(String format, Object ... args) {
+ if(format.contains("%s")) {
+ subject = String.format(format, args);
+ } else {
+ subject = format;
+ }
+ return this;
+ }
+
+
+ public Email signature(String format, Object ... args) {
+ sig = String.format(format, args);
+ return this;
+ }
+
+ public void msg(Message msg) {
+ this.msg = msg;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Organization org, String text) {
+ StringBuilder sb = new StringBuilder();
+ if(preamble!=null) {
+ sb.append(lineIndent);
+ sb.append(preamble);
+ sb.append("\n\n");
+ }
+
+ if(msg!=null) {
+ msg.msg(sb,lineIndent);
+ sb.append("\n");
+ }
+
+ if(sig!=null) {
+ sb.append(sig);
+ sb.append("\n");
+ }
+
+ long ct = System.currentTimeMillis();
+ long wait = ct-lastSent;
+ lastSent = ct;
+ if(wait < 100) { // 10 per second
+ try {
+ Thread.sleep(wait);
+ } catch (InterruptedException e) {
+ }
+ }
+ return exec(trans,org,sb);
+ }
+
+ protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder sb) {
+ try {
+ /* int status = */
+ org.sendEmail(trans,
+ toList,
+ ccList,
+ subject,
+ sb.toString(),
+ false);
+ } catch (Exception e) {
+ return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());
+ }
+ return Result.ok();
+
+ }
+
+ public void log(PrintStream ps, String text) {
+ ps.print(Chrono.dateTime());
+ boolean first = true;
+ for(String s : toList) {
+ if(first) {
+ first = false;
+ ps.print(": ");
+ } else {
+ ps.print(", ");
+ }
+ ps.print(s);
+ }
+ if(!ccList.isEmpty()) {
+ first=true;
+ for(String s : ccList) {
+ if(first) {
+ first = false;
+ ps.print(" [");
+ } else {
+ ps.print(", ");
+ }
+ ps.print(s);
+ }
+ ps.print(']');
+ }
+
+ ps.print(' ');
+ ps.println(text);
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/EmailPrint.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/EmailPrint.java
new file mode 100644
index 00000000..dba02426
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/EmailPrint.java
@@ -0,0 +1,98 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.PrintStream;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.Organization;
+
+public class EmailPrint extends Email {
+
+ private static final int LINE_LENGTH = 100;
+
+ public EmailPrint(String... defaultCC) {
+ super(defaultCC);
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.actions.Email#exec(org.onap.aaf.auth.org.test.Organization, java.lang.StringBuilder)
+ */
+ @Override
+ protected Result<Void> exec(AuthzTrans trans, Organization org, StringBuilder msg) {
+ PrintStream out = System.out;
+ boolean first = true;
+ out.print("To: ");
+ for(String s: toList) {
+ if(first) {first = false;}
+ else {out.print(',');}
+ out.print(s);
+ }
+ out.println();
+
+ first = true;
+ out.print("CC: ");
+ for(String s: ccList) {
+ if(first) {first = false;}
+ else {out.print(',');}
+ out.print(s);
+ }
+ out.println();
+
+ out.print("Subject: ");
+ out.println(subject);
+ out.println();
+ boolean go = true;
+
+ for(int start=0, end=LINE_LENGTH;go;start=end,end=Math.min(msg.length(), start+LINE_LENGTH)) {
+ int ret = msg.indexOf("\n",start+1);
+ switch(ret) {
+ case -1:
+ out.println(msg.substring(start,end));
+ break;
+ case 0:
+ end=start+1;
+ out.println();
+ break;
+ default:
+ if(ret<end) {
+ end = ret;
+ }
+ if(end==start+LINE_LENGTH) {
+ // Word-wrapping
+ ret = msg.lastIndexOf(" ", end);
+ if(ret>start && ret<end) {
+ end=ret+1;
+ }
+ out.println(msg.substring(start,end));
+ } else {
+ out.print(msg.substring(start,end));
+ }
+ }
+ go = end<msg.length();
+ }
+ return Result.ok();
+
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/FuturePrint.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/FuturePrint.java
new file mode 100644
index 00000000..34a16d2a
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/FuturePrint.java
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Future;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class FuturePrint implements Action<Future,Void,String> {
+ private String info;
+
+ public FuturePrint(String text) {
+ this.info = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Future f, String text) {
+ trans.info().log(info,f.id(),f.memo(),"expiring on",Chrono.dateOnlyStamp(f.expires()));
+ return Result.ok();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Key.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Key.java
new file mode 100644
index 00000000..8c39e47d
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Key.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+public interface Key<HELPER> {
+ public String key(HELPER H);
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Message.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Message.java
new file mode 100644
index 00000000..98fc0054
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/Message.java
@@ -0,0 +1,53 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class Message {
+ public final List<String> lines;
+
+ public Message() {
+ lines = new ArrayList<String>();
+ }
+
+ public void clear() {
+ lines.clear();
+ }
+
+ public String line(String format, Object ... args) {
+ String rv=String.format(format, args);
+ lines.add(rv);
+ return rv;
+ }
+
+ public void msg(StringBuilder sb, String lineIndent) {
+ if(lines.size()>0) {
+ for(String line : lines) {
+ sb.append(lineIndent);
+ sb.append(line);
+ sb.append('\n');
+ }
+ }
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSACreate.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSACreate.java
new file mode 100644
index 00000000..3d215871
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSACreate.java
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.NsAttrib;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class NSACreate extends ActionDAO<NsAttrib,Void,String> {
+ public NSACreate(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public NSACreate(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, NsAttrib nsa, String text) {
+ if(dryRun) {
+ trans.info().printf("Would Create %s Attrib '%s=%s' in %s",text,nsa.key,nsa.value,nsa.ns);
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.nsDAO.dao().attribAdd(trans, nsa.ns, nsa.key, nsa.value);
+ if(rv.isOK()) {
+ trans.info().printf("%s - Created Attrib '%s=%s' in %s",text,nsa.key,nsa.value,nsa.ns);
+ } else {
+ trans.error().printf("Error Creating Attrib '%s=%s' in %s - %s",nsa.key,nsa.value,nsa.ns,rv.details);
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSADelete.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSADelete.java
new file mode 100644
index 00000000..4b976822
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSADelete.java
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.NsAttrib;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class NSADelete extends ActionDAO<NsAttrib,Void,String> {
+ public NSADelete(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public NSADelete(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, NsAttrib nsa, String text) {
+ if(dryRun) {
+ trans.info().printf("Would Delete %s Attrib '%s' in %s",text,nsa.key,nsa.ns);
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.nsDAO.dao().attribRemove(trans, nsa.ns, nsa.key);
+ if(rv.isOK()) {
+ trans.info().printf("%s - Deleted Attrib '%s' in %s",text,nsa.key,nsa.value,nsa.ns);
+ } else {
+ trans.error().printf("Error Deleting Attrib '%s' in %s - %s",nsa.key,nsa.value,nsa.ns,rv.details);
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSDescUpdate.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSDescUpdate.java
new file mode 100644
index 00000000..368c8452
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/NSDescUpdate.java
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.NS;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class NSDescUpdate extends ActionDAO<NS,Void,String> {
+ public NSDescUpdate(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public NSDescUpdate(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, NS ns, String desc) {
+ if(dryRun) {
+ trans.info().printf("Would Update '%s' Description to '%s'",ns,desc);
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.nsDAO.dao().addDescription(trans, ns.name, desc);
+ if(rv.isOK()) {
+ trans.info().printf("Updated '%s' Description to '%s'",ns,desc);
+ } else {
+ trans.error().printf("Error Updating '%s' Description to '%s' - %s",ns,desc,rv.details);
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermCreate.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermCreate.java
new file mode 100644
index 00000000..5f3ab202
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermCreate.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.PermDAO;
+import org.onap.aaf.auth.dao.cass.PermDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Perm;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+
+public class PermCreate extends ActionDAO<Perm,Data,String> {
+ public PermCreate(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public PermCreate(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Data> exec(AuthzTrans trans, Perm p,String text) {
+ PermDAO.Data pdd = new PermDAO.Data();
+ pdd.ns = p.ns;
+ pdd.type = p.type;
+ pdd.instance = p.instance;
+ pdd.action = p.action;
+ pdd.description = p.description;
+ pdd.roles = p.roles;
+
+ if(dryRun) {
+ trans.info().log("Would Create Perm:",text,p.fullType());
+ return Result.ok(pdd);
+ } else {
+ Result<Data> rv = q.permDAO.create(trans, pdd); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Created Perm:",text,p.fullType());
+ } else {
+ trans.error().log("Error Creating Role -",rv.details,":",p.fullType());
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermDelete.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermDelete.java
new file mode 100644
index 00000000..02fd3c6c
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermDelete.java
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.PermDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Perm;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class PermDelete extends ActionDAO<Perm,Void,String> {
+ public PermDelete(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public PermDelete(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Perm p,String text) {
+ PermDAO.Data pdd = new PermDAO.Data();
+ pdd.ns = p.ns;
+ pdd.type = p.type;
+ pdd.instance = p.instance;
+ pdd.action = p.action;
+ if(dryRun) {
+ trans.info().log("Would Delete Perm:",text,p.fullType());
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.permDAO.delete(trans, pdd, true); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Deleted Perm:",text,p.fullType());
+ } else {
+ trans.error().log("Error Deleting Perm -",rv.details,":",p.fullType());
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermModify.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermModify.java
new file mode 100644
index 00000000..9b60cee1
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/PermModify.java
@@ -0,0 +1,141 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.List;
+
+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.PermDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Perm;
+import org.onap.aaf.auth.helpers.Role;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class PermModify extends ActionDAO<Perm,PermDAO.Data,PermModify.Modify> {
+ public PermModify(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public PermModify(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<PermDAO.Data> exec(AuthzTrans trans, final Perm p, final Modify modify) {
+ Result<List<PermDAO.Data>> rr = q.permDAO.read(trans, p.ns,p.type,p.instance,p.action);
+ if(dryRun) {
+ if(rr.isOKhasData()) {
+ return Result.ok(rr.value.get(0));
+ } else {
+ return Result.err(Result.ERR_NotFound, "Data not Found " + p.toString());
+ }
+ } else {
+ Result<PermDAO.Data> rv = null;
+ if(rr.isOKhasData()) {
+ for(final Data d : rr.value) {
+ modify.change(d);
+ if(d.ns.equals(p.ns) && d.type.equals(p.type) && d.instance.equals(p.instance) && d.action.equals(p.action)) {
+ // update for fields
+ // In either case, adjust Permissions
+ for(String r : d.roles) {
+ if(!p.roles.contains(r)) {
+ q.permDAO.dao().addRole(trans, d, r);
+ }
+ }
+ for(String r : p.roles) {
+ if(!d.roles.contains(r)) {
+ q.permDAO.dao().delRole(trans, d, r);
+ }
+ }
+ rv = Result.ok(d);
+ } else {
+ for(String r : d.roles) {
+ Role role = Role.keys.get(r);
+ if(role.perms.contains(p.encode())) {
+ modify.roleModify().exec(trans, role, new RoleModify.Modify() {
+ @Override
+ public PermModify permModify() {
+ return PermModify.this;
+ }
+
+ @Override
+ public void change(RoleDAO.Data rdd) {
+ rdd.perms.remove(p.encode());
+ rdd.perms.add(d.encode());
+ }
+ });
+ }
+ }
+
+ rv = q.permDAO.create(trans, d);
+ if(rv.isOK()) {
+ PermDAO.Data pdd = new PermDAO.Data();
+ pdd.ns = p.ns;
+ pdd.type = p.type;
+ pdd.instance = p.instance;
+ pdd.action = p.action;
+ q.permDAO.delete(trans, pdd, false);
+ trans.info().printf("Updated %s|%s|%s|%s to %s|%s|%s|%s\n",
+ p.ns, p.type, p.instance, p.action,
+ d.ns, d.type, d.instance, d.action);
+ } else {
+ trans.info().log(rv.errorString());
+ }
+ }
+
+ }
+ } else {
+ rv = Result.err(rr);
+ }
+ if(rv==null) {
+ rv = Result.err(Status.ERR_General,"Never get to this code");
+ }
+
+ return rv;
+ }
+ }
+
+ public static interface Modify {
+ void change(PermDAO.Data ur);
+ RoleModify roleModify();
+ }
+
+ public Result<Void> delete(AuthzTrans trans, Perm p) {
+ if(dryRun) {
+ return Result.ok();
+ } else {
+ PermDAO.Data data = new PermDAO.Data();
+ data.ns=p.ns;
+ data.type = p.type;
+ data.instance = p.instance;
+ data.action = p.action;
+ return q.permDAO.delete(trans,data,false);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleCreate.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleCreate.java
new file mode 100644
index 00000000..50d163ab
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleCreate.java
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.dao.cass.RoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Role;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class RoleCreate extends ActionDAO<Role,Data,String> {
+ public RoleCreate(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public RoleCreate(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Data> exec(AuthzTrans trans, Role r,String text) {
+ RoleDAO.Data rdd = new RoleDAO.Data();
+ rdd.ns = r.ns;
+ rdd.name = r.name;
+ rdd.description = r.description;
+ rdd.perms = r.perms;
+
+ if(dryRun) {
+ trans.info().log("Would Create Role:",text,r.fullName());
+ return Result.ok(rdd);
+ } else {
+ Result<Data> rv = q.roleDAO.create(trans, rdd); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Created Role:",text,r.fullName());
+ } else {
+ trans.error().log("Error Creating Role -",rv.details,":",r.fullName());
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleDelete.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleDelete.java
new file mode 100644
index 00000000..cbe3c1c5
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleDelete.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Role;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class RoleDelete extends ActionDAO<Role,Void,String> {
+ public RoleDelete(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public RoleDelete(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Role r,String text) {
+ if(dryRun) {
+ trans.info().log("Would Delete Role:",text,r.fullName());
+ return Result.ok();
+ } else {
+ RoleDAO.Data rdd = new RoleDAO.Data();
+ rdd.ns = r.ns;
+ rdd.name = r.name;
+ Result<Void> rv = q.roleDAO.delete(trans, rdd, true); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Deleted Role:",text,r.fullName());
+ } else {
+ trans.error().log("Error Deleting Role -",rv.details,":",r.fullName());
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleModify.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleModify.java
new file mode 100644
index 00000000..c72a9d8f
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/RoleModify.java
@@ -0,0 +1,152 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.List;
+
+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.RoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Perm;
+import org.onap.aaf.auth.helpers.Role;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class RoleModify extends ActionDAO<Role,RoleDAO.Data,RoleModify.Modify> {
+ public RoleModify(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster, dryRun);
+ }
+
+ public RoleModify(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<RoleDAO.Data> exec(final AuthzTrans trans, final Role r,final RoleModify.Modify modify) {
+ Result<List<Data>> rr = q.roleDAO.read(trans, r.ns,r.name);
+ if(dryRun) {
+ if(rr.isOKhasData()) {
+ return Result.ok(rr.value.get(0));
+ } else {
+ return Result.err(Result.ERR_NotFound, "Data not Found " + r.toString());
+ }
+ } else {
+ Result<Data> rv = null;
+ if(rr.isOKhasData()) {
+ for(final Data d : rr.value) {
+ modify.change(d);
+ if(d.ns.equals(r.ns) && d.name.equals(r.name)) {
+ // update for fields
+ // In either case, adjust Roles
+ for(String p : d.perms) {
+ if(!r.perms.contains(p)) {
+ Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans, q, p);
+ if(rpdd.isOKhasData()) {
+ q.roleDAO.dao().addPerm(trans, d, rpdd.value);
+ }
+ }
+ }
+ for(String p : r.perms) {
+ if(!d.perms.contains(p)) {
+ Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans, q, p);
+ if(rpdd.isOKhasData()) {
+ q.roleDAO.dao().delPerm(trans, d, rpdd.value);
+ }
+ }
+ }
+ rv = Result.ok(d);
+ } else {
+ for(String p : d.perms) {
+ Perm perm = Perm.keys.get(p);
+ if(perm!=null) {
+ if(perm.roles.contains(r.encode())) {
+ modify.permModify().exec(trans, perm, new PermModify.Modify() {
+ @Override
+ public RoleModify roleModify() {
+ return RoleModify.this;
+ }
+
+ @Override
+ public void change(PermDAO.Data pdd) {
+ pdd.roles.remove(r.encode());
+ pdd.roles.add(d.encode());
+ }
+ });
+ }
+ }
+ }
+ Result<List<Data>> preexist = q.roleDAO.read(trans, d);
+ if(preexist.isOKhasData()) {
+ Data rdd = preexist.value.get(0);
+ for(String p : d.perms) {
+ Result<PermDAO.Data> perm = PermDAO.Data.decode(trans, q, p);
+ if(perm.isOKhasData()) {
+ q.roleDAO.dao().addPerm(trans,rdd, perm.value);
+ }
+ }
+ rv = Result.ok(rdd);
+ } else {
+ rv = q.roleDAO.create(trans, d);
+ }
+ if(rv.isOK()) {
+ trans.info().printf("Updating %s|%s to %s|%s", r.ns, r.name, d.ns, d.name);
+ RoleDAO.Data rmme = new RoleDAO.Data();
+ rmme.ns=r.ns;
+ rmme.name=r.name;
+ q.roleDAO.delete(trans, rmme, false);
+
+ } else {
+ trans.info().log(rv.errorString());
+ }
+ }
+ }
+ } else {
+ rv = Result.err(rr);
+ }
+ if(rv==null) {
+ rv = Result.err(Status.ERR_General,"Never get to this code");
+ }
+ return rv;
+ }
+ }
+
+ public static interface Modify {
+ void change(RoleDAO.Data ur);
+ PermModify permModify();
+ }
+
+ public Result<Void> delete(AuthzTrans trans, Role r) {
+ if(dryRun) {
+ return Result.ok();
+ } else {
+ RoleDAO.Data data = new RoleDAO.Data();
+ data.ns=r.ns;
+ data.name = r.name;
+ return q.roleDAO.delete(trans,data,false);
+ }
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URAdd.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URAdd.java
new file mode 100644
index 00000000..50a5a8f0
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URAdd.java
@@ -0,0 +1,57 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class URAdd extends ActionDAO<UserRole,UserRoleDAO.Data,String> {
+ public URAdd(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public URAdd(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Data> exec(AuthzTrans trans, UserRole ur, String text) {
+ if(dryRun) {
+ trans.info().log("Would Add:",text,ur.role(),ur.user(),"on",Chrono.dateOnlyStamp(ur.expires()));
+ return Result.ok(ur.urdd());
+ } else {
+ Result<Data> rv = q.userRoleDAO.create(trans, ur.urdd());
+ trans.info().log("Added:",text,ur.role(),ur.user(),"on",Chrono.dateOnlyStamp(ur.expires()));
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URDelete.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URDelete.java
new file mode 100644
index 00000000..9bc7da49
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URDelete.java
@@ -0,0 +1,59 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class URDelete extends ActionDAO<UserRole,Void,String> {
+ public URDelete(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public URDelete(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, UserRole ur,String text) {
+ if(dryRun) {
+ trans.info().log("Would Delete UserRole:",text,ur.user(),ur.role(),"on",Chrono.dateOnlyStamp(ur.expires()));
+ return Result.ok();
+ } else {
+ Result<Void> rv = q.userRoleDAO.delete(trans,ur.urdd(), true); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Deleted UserRole:",text,ur.user(),ur.role(),"on",Chrono.dateOnlyStamp(ur.expires()));
+ } else {
+ trans.error().log("Error Deleting User Role -",rv.details,":",ur.user(),ur.role(),"on",Chrono.dateOnlyStamp(ur.expires()) );
+ }
+ return rv;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApprove.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApprove.java
new file mode 100644
index 00000000..17d9cc01
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApprove.java
@@ -0,0 +1,111 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.cass.NsDAO;
+import org.onap.aaf.auth.dao.hl.Function;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Approval;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.Organization.Expiration;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class URFutureApprove extends ActionDAO<UserRole, String,String> implements Action<UserRole,String,String>, Key<UserRole> {
+ private final Date start, expires;
+
+ public URFutureApprove(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans,cluster, dryRun);
+ GregorianCalendar gc = new GregorianCalendar();
+ start = gc.getTime();
+ expires = trans.org().expiration(gc, Expiration.Future).getTime();
+ }
+
+ public URFutureApprove(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ GregorianCalendar gc = new GregorianCalendar();
+ start = gc.getTime();
+ expires = trans.org().expiration(gc, Expiration.Future).getTime();
+ }
+
+ @Override
+ public Result<String> exec(AuthzTrans trans, UserRole ur,String text) {
+ if(dryRun) {
+ return Result.ok(text);
+ } else {
+ Result<NsDAO.Data> rns = q.deriveNs(trans, ur.ns());
+ if(rns.isOK()) {
+
+ FutureDAO.Data data = new FutureDAO.Data();
+ data.id=null; // let Create function assign UUID
+ data.target=Function.FOP_USER_ROLE;
+
+ data.memo = key(ur);
+ data.start = start;
+ data.expires = ur.expires();
+ try {
+ data.construct = ur.urdd().bytify();
+ } catch (IOException e) {
+ return Result.err(e);
+ }
+ Result<String> rfuture = f.createFuture(trans, data, Function.FOP_USER_ROLE, ur.user(), rns.value, FUTURE_OP.A);
+ if(rfuture.isOK()) {
+ trans.info().log(rfuture.value, text, ur.user(), data.memo);
+ } else {
+ trans.error().log(rfuture.details, text);
+ }
+ return rfuture;
+ } else {
+ return Result.err(rns);
+ }
+ }
+ }
+
+ @Override
+ public String key(UserRole ur) {
+ String expire;
+ if(expires.before(start)) {
+ expire = "' - EXPIRED ";
+ } else {
+ expire = "' - expiring ";
+ }
+
+ if(Question.OWNER.equals(ur.rname())) {
+ return Approval.RE_VALIDATE_OWNER + ur.ns() + expire + Chrono.dateOnlyStamp(ur.expires());
+ } else if(Question.ADMIN.equals(ur.rname())) {
+ return Approval.RE_VALIDATE_ADMIN + ur.ns() + expire + Chrono.dateOnlyStamp(ur.expires());
+ } else {
+ return Approval.RE_APPROVAL_IN_ROLE + ur.role() + expire + Chrono.dateOnlyStamp(ur.expires());
+ }
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java
new file mode 100644
index 00000000..6cf2c53e
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFutureApproveExec.java
@@ -0,0 +1,108 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO.Data;
+import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
+import org.onap.aaf.auth.dao.hl.Function.Lookup;
+import org.onap.aaf.auth.dao.hl.Function.OP_STATUS;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Approval;
+import org.onap.aaf.auth.helpers.Future;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class URFutureApproveExec extends ActionDAO<List<Approval>, OP_STATUS, Future> {
+
+ public URFutureApproveExec(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans,cluster, dryRun);
+ }
+
+ public URFutureApproveExec(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<OP_STATUS> exec(AuthzTrans trans, List<Approval> app, Future future) {
+ if(dryRun) {
+ return Result.err(Result.ERR_ActionNotCompleted,"Not Executed");
+ } else {
+ // Save on Lookups
+ final List<ApprovalDAO.Data> apprs = new ArrayList<ApprovalDAO.Data>();
+ final List<UserRoleDAO.Data> urs = new ArrayList<UserRoleDAO.Data>();
+ for(Approval a : app) {
+ apprs.add(a.add);
+ UserRole ur = UserRole.get(a.add.user, future.role);
+ if(ur!=null) {
+ urs.add(ur.urdd());
+ }
+ }
+ Result<OP_STATUS> rv = f.performFutureOp(trans, FUTURE_OP.A, future.fdd,
+ new Lookup<List<ApprovalDAO.Data>>() {
+ @Override
+ public List<Data> get(AuthzTrans trans, Object ... noop) {
+ return apprs;
+ }
+ },
+ new Lookup<UserRoleDAO.Data>() {
+ @Override
+ public UserRoleDAO.Data get(AuthzTrans trans, Object ... keys) {
+ List<UserRole> lur = UserRole.byUser.get(keys[0]);
+ if(lur!=null) {
+ for(UserRole ur : lur) {
+ if(ur.role().equals(keys[1])) {
+ return ur.urdd();
+ }
+ }
+ }
+ return null;
+ }
+ });
+ if(rv.isOK()) {
+ switch(rv.value) {
+ case D:
+ trans.info().printf("Denied %s on %s", future.memo(),future.fdd.target);
+ break;
+ case E:
+ trans.info().printf("Completed %s on %s", future.memo(),future.fdd.target);
+ break;
+ case L:
+ trans.info().printf("Future %s on %s has lapsed", future.memo(),future.fdd.target);
+ break;
+ default:
+ }
+ } else {
+ trans.error().log("Error completing",future.memo(),rv.errorString());
+ }
+ return rv;
+ }
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFuturePrint.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFuturePrint.java
new file mode 100644
index 00000000..83a24c21
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URFuturePrint.java
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.util.Chrono;
+
+
+public class URFuturePrint implements Action<UserRole,String,String> {
+ private String info;
+
+ public URFuturePrint(String text) {
+ this.info = text;
+ }
+
+ @Override
+ public Result<String> exec(AuthzTrans trans, UserRole ur, String text) {
+ trans.info().log(info,text,ur.user(),"to",ur.role(),"on",Chrono.dateOnlyStamp(ur.expires()));
+ return Result.ok(info);
+ }} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URModify.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URModify.java
new file mode 100644
index 00000000..3f65a6a4
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URModify.java
@@ -0,0 +1,80 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.Status;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+
+import com.datastax.driver.core.Cluster;
+
+public class URModify extends ActionDAO<UserRole,Void,URModify.Modify> {
+ public URModify(AuthzTrans trans, Cluster cluster, boolean dryRun) throws APIException, IOException {
+ super(trans, cluster,dryRun);
+ }
+
+ public URModify(AuthzTrans trans, ActionDAO<?,?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, UserRole ur,Modify modify) {
+ if(dryRun) {
+ trans.info().printf("Would Update %s %s", ur.user(), ur.role());
+ return Result.ok();
+ } else {
+ Result<List<Data>> rr = q.userRoleDAO.read(trans, ur.user(),ur.role());
+ if(rr.notOKorIsEmpty()) {
+ return Result.err(rr);
+ }
+ for(Data d : rr.value) {
+ modify.change(d);
+ if(!(ur.expires().equals(d.expires))) {
+ ur.expires(d.expires);
+ }
+ if(ur.user().equals(d.user) && ur.role().equals(d.role)){
+ Result<Void> rv = q.userRoleDAO.update(trans, d);
+ if(rv.isOK()) {
+ trans.info().printf("Updated %s %s to %s", ur.user(), ur.role(), d.toString());
+ } else {
+ trans.info().log(rv.errorString());
+ }
+ } else {
+ return Result.err(Status.ERR_Denied, "You cannot change the key of this Data");
+ }
+ }
+ return Result.err(Status.ERR_UserRoleNotFound,"No User Role with %s %s",ur.user(),ur.role());
+ }
+ }
+
+ public static interface Modify {
+ void change(UserRoleDAO.Data ur);
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPrint.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPrint.java
new file mode 100644
index 00000000..a9bdf9ca
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPrint.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class URPrint implements Action<UserRole,Void,String> {
+ private String info;
+
+ public URPrint(String text) {
+ this.info = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, UserRole ur, String text) {
+ trans.info().log(info,text,ur.user(),"to",ur.role(),"expiring on",Chrono.dateOnlyStamp(ur.expires()));
+ return Result.ok();
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPunt.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPunt.java
new file mode 100644
index 00000000..8676ef33
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/actions/URPunt.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.Cluster;
+
+public class URPunt extends ActionPuntDAO<UserRole,Void,String> {
+ public URPunt(AuthzTrans trans, Cluster cluster, int months, int range, boolean dryRun) throws APIException, IOException {
+ super(trans,cluster, months, range,dryRun);
+ }
+
+ public URPunt(AuthzTrans trans, ActionDAO<?,?,?> adao, int months, int range) {
+ super(trans, adao, months, range);
+ }
+
+ public Result<Void> exec(AuthzTrans trans, UserRole ur, String text) {
+ if(dryRun) {
+ trans.info().log("Would Update User",ur.user(),"and Role", ur.role(), text);
+ return Result.ok();
+ } else {
+ Result<List<Data>> read = q.userRoleDAO.read(trans, ur.user(), ur.role());
+ if(read.isOK()) {
+ for(UserRoleDAO.Data data : read.value) {
+ Date from = data.expires;
+ data.expires = puntDate(from);
+ if(data.expires.compareTo(from)<=0) {
+ trans.debug().printf("Error: %s is same or before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+ } else {
+ trans.info().log("Updating User",ur.user(),"and Role", ur.role(), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires), text);
+ q.userRoleDAO.update(trans, data);
+ }
+ }
+ return Result.ok();
+ } else {
+ return Result.err(read);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/AafEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/AafEntryConverter.java
new file mode 100644
index 00000000..637ee569
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/AafEntryConverter.java
@@ -0,0 +1,46 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import java.util.Set;
+
+public abstract class AafEntryConverter {
+
+ protected String formatSet(Set<String> set) {
+ if (set==null || set.isEmpty()) return "";
+ StringBuilder sb = new StringBuilder();
+ int curr = 0;
+ sb.append("{");
+ for (String s : set) {
+ sb.append("'");
+ sb.append(s);
+ sb.append("'");
+ if (set.size() != curr + 1) {
+ sb.append(",");
+ }
+ curr++;
+ }
+ sb.append("}");
+ return sb.toString();
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/CredEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/CredEntryConverter.java
new file mode 100644
index 00000000..6153e75e
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/CredEntryConverter.java
@@ -0,0 +1,48 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import org.onap.aaf.auth.dao.cass.CredDAO;
+
+import com.datastax.driver.core.utils.Bytes;
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class CredEntryConverter extends AafEntryConverter implements CSVEntryConverter<CredDAO.Data> {
+ private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ";
+
+ @Override
+ public String[] convertEntry(CredDAO.Data cd) {
+ String[] columns = new String[5];
+
+ columns[0] = cd.id;
+ columns[1] = String.valueOf(cd.type);
+ DateFormat df = new SimpleDateFormat(DATE_FORMAT);
+ columns[2] = df.format(cd.expires);
+ columns[3] = Bytes.toHexString(cd.cred);
+ columns[4] = (cd.ns==null)?"":cd.ns;
+
+ return columns;
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/NsEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/NsEntryConverter.java
new file mode 100644
index 00000000..b2767ab4
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/NsEntryConverter.java
@@ -0,0 +1,46 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import org.onap.aaf.auth.dao.cass.NsDAO;
+
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class NsEntryConverter extends AafEntryConverter implements CSVEntryConverter<NsDAO.Data> {
+
+ @Override
+ public String[] convertEntry(NsDAO.Data nsd) {
+ String[] columns = new String[5];
+
+ columns[0] = nsd.name;
+ // Jonathan changed from "scope" to "type"
+ columns[1] = String.valueOf(nsd.type);
+ //TODO Chris: need to look at this
+// columns[2] = formatSet(nsd.admin);
+// columns[3] = formatSet(nsd.responsible);
+// columns[4] = nsd.description==null?"":nsd.description;
+ columns[5] = nsd.description==null?"":nsd.description;
+
+ return columns;
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/PermEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/PermEntryConverter.java
new file mode 100644
index 00000000..12995f68
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/PermEntryConverter.java
@@ -0,0 +1,43 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import org.onap.aaf.auth.dao.cass.PermDAO;
+
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class PermEntryConverter extends AafEntryConverter implements CSVEntryConverter<PermDAO.Data> {
+
+ @Override
+ public String[] convertEntry(PermDAO.Data pd) {
+ String[] columns = new String[6];
+
+ columns[0] = pd.ns;
+ columns[1] = pd.type;
+ columns[2] = pd.instance;
+ columns[3] = pd.action;
+ columns[4] = formatSet(pd.roles);
+ columns[5] = pd.description==null?"":pd.description;
+
+ return columns;
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/RoleEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/RoleEntryConverter.java
new file mode 100644
index 00000000..e236f3c3
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/RoleEntryConverter.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import org.onap.aaf.auth.dao.cass.RoleDAO;
+
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class RoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<RoleDAO.Data> {
+
+ @Override
+ public String[] convertEntry(RoleDAO.Data rd) {
+ String[] columns = new String[4];
+
+ columns[0] = rd.ns;
+ columns[1] = rd.name;
+ columns[2] = formatSet(rd.perms);
+ columns[3] = rd.description==null?"":rd.description;
+
+ return columns;
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/UserRoleEntryConverter.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/UserRoleEntryConverter.java
new file mode 100644
index 00000000..8730f945
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/entryConverters/UserRoleEntryConverter.java
@@ -0,0 +1,45 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+
+import com.googlecode.jcsv.writer.CSVEntryConverter;
+
+public class UserRoleEntryConverter extends AafEntryConverter implements CSVEntryConverter<UserRoleDAO.Data> {
+ private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ssZ";
+
+ @Override
+ public String[] convertEntry(UserRoleDAO.Data urd) {
+ String[] columns = new String[3];
+
+ columns[0] = urd.user;
+ columns[1] = urd.role;
+ DateFormat df = new SimpleDateFormat(DATE_FORMAT);
+ columns[2] = df.format(urd.expires);
+
+ return columns;
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approval.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approval.java
new file mode 100644
index 00000000..0bd9397c
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approval.java
@@ -0,0 +1,309 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Approval implements CacheChange.Data {
+ public static final String RE_APPROVAL_IN_ROLE = "Re-Approval in Role '";
+ public static final String RE_VALIDATE_ADMIN = "Re-Validate as Administrator for AAF Namespace '";
+ public static final String RE_VALIDATE_OWNER = "Re-Validate Ownership for AAF Namespace '";
+
+ public static TreeMap<String,List<Approval>> byApprover = new TreeMap<String,List<Approval>>();
+ public static TreeMap<String,List<Approval>> byUser = new TreeMap<String,List<Approval>>();
+ public static TreeMap<UUID,List<Approval>> byTicket = new TreeMap<UUID,List<Approval>>();
+ private final static CacheChange<Approval> cache = new CacheChange<Approval>();
+
+ public final ApprovalDAO.Data add;
+ private String role;
+
+ public Approval(UUID id, UUID ticket, String approver, Date last_notified,
+ String user, String memo, String operation, String status, String type, long updated) {
+ add = new ApprovalDAO.Data();
+ add.id = id;
+ add.ticket = ticket;
+ add.approver = approver;
+ add.last_notified = last_notified;
+ add.user = user;
+ add.memo = memo;
+ add.operation = operation;
+ add.status = status;
+ add.type = type;
+ add.updated = new Date(updated);
+ role = roleFromMemo(memo);
+ }
+
+ public static String roleFromMemo(String memo) {
+ if(memo==null) {
+ return null;
+ }
+ int first = memo.indexOf('\'');
+ if(first>=0) {
+ int second = memo.indexOf('\'', ++first);
+ if(second>=0) {
+ String role = memo.substring(first, second);
+ if(memo.startsWith(RE_VALIDATE_ADMIN)) {
+ return role + ".admin";
+ } else if(memo.startsWith(RE_VALIDATE_OWNER)) {
+ return role + ".owner";
+ } else if(memo.startsWith(RE_APPROVAL_IN_ROLE)) {
+ return role;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static void load(Trans trans, Session session, Creator<Approval> creator ) {
+ trans.info().log( "query: " + creator.select() );
+ TimeTaken tt = trans.start("Load Notify", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(creator.select());
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ tt = trans.start("Process Notify", Env.SUB);
+
+ try {
+ List<Approval> ln;
+ for(Row row : results.all()) {
+ ++count;
+ try {
+ Approval app = creator.create(row);
+ String person = app.getApprover();
+ if(person!=null) {
+ ln = byApprover.get(person);
+ if(ln==null) {
+ ln = new ArrayList<Approval>();
+ byApprover.put(app.getApprover(), ln);
+ }
+ ln.add(app);
+ }
+
+
+ person = app.getUser();
+ if(person!=null) {
+ ln = byUser.get(person);
+ if(ln==null) {
+ ln = new ArrayList<Approval>();
+ byUser.put(app.getUser(), ln);
+ }
+ ln.add(app);
+ }
+ UUID ticket = app.getTicket();
+ if(ticket!=null) {
+ ln = byTicket.get(ticket);
+ if(ln==null) {
+ ln = new ArrayList<Approval>();
+ byTicket.put(app.getTicket(), ln);
+ }
+ ln.add(app);
+ }
+ } finally {
+ tt.done();
+ }
+ }
+ } finally {
+ tt.done();
+ trans.info().log("Found",count,"Approval Records");
+ }
+ }
+
+ @Override
+ public void expunge() {
+ List<Approval> la = byApprover.get(getApprover());
+ if(la!=null) {
+ la.remove(this);
+ }
+
+ la = byUser.get(getUser());
+ if(la!=null) {
+ la.remove(this);
+ }
+ UUID ticket = this.add==null?null:this.add.ticket;
+ if(ticket!=null) {
+ la = byTicket.get(this.add.ticket);
+ if(la!=null) {
+ la.remove(this);
+ }
+ }
+ }
+
+ public void update(AuthzTrans trans, ApprovalDAO apprDAO, boolean dryRun) {
+ if(dryRun) {
+ trans.info().printf("Would update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified);
+ } else {
+ trans.info().printf("Update Approval %s, %s, last_notified %s",add.id,add.status,add.last_notified);
+ apprDAO.update(trans, add);
+ }
+ }
+
+ public static Creator<Approval> v2_0_17 = new Creator<Approval>() {
+ @Override
+ public Approval create(Row row) {
+ return new Approval(row.getUUID(0), row.getUUID(1), row.getString(2), row.getTimestamp(3),
+ row.getString(4),row.getString(5),row.getString(6),row.getString(7),row.getString(8)
+ ,row.getLong(9)/1000);
+ }
+
+ @Override
+ public String select() {
+ return "select id,ticket,approver,last_notified,user,memo,operation,status,type,WRITETIME(status) from authz.approval";
+ }
+ };
+
+ /**
+ * @return the lastNotified
+ */
+ public Date getLast_notified() {
+ return add.last_notified;
+ }
+ /**
+ * @param lastNotified the lastNotified to set
+ */
+ public void setLastNotified(Date last_notified) {
+ add.last_notified = last_notified;
+ }
+ /**
+ * @return the status
+ */
+ public String getStatus() {
+ return add.status;
+ }
+ /**
+ * @param status the status to set
+ */
+ public void setStatus(String status) {
+ add.status = status;
+ }
+ /**
+ * @return the id
+ */
+ public UUID getId() {
+ return add.id;
+ }
+ /**
+ * @return the ticket
+ */
+ public UUID getTicket() {
+ return add.ticket;
+ }
+ /**
+ * @return the approver
+ */
+ public String getApprover() {
+ return add.approver;
+ }
+ /**
+ * @return the user
+ */
+ public String getUser() {
+ return add.user;
+ }
+ /**
+ * @return the memo
+ */
+ public String getMemo() {
+ return add.memo;
+ }
+ /**
+ * @return the operation
+ */
+ public String getOperation() {
+ return add.operation;
+ }
+ /**
+ * @return the type
+ */
+ public String getType() {
+ return add.type;
+ }
+ public void lapsed() {
+ add.ticket=null;
+ add.status="lapsed";
+ }
+
+ public String getRole() {
+ return role;
+ }
+
+ public String toString() {
+ return getUser() + ' ' + getMemo();
+ }
+
+ public void delayDelete(AuthzTrans trans, ApprovalDAO ad, boolean dryRun, String text) {
+ if(dryRun) {
+ trans.info().log(text,"- Would Delete: Approval",getId(),"on ticket",getTicket(),"for",getApprover());
+ } else {
+ Result<Void> rv = ad.delete(trans, add, false);
+ if(rv.isOK()) {
+ trans.info().log(text,"- Deleted: Approval",getId(),"on ticket",getTicket(),"for",getApprover());
+ cache.delayedDelete(this);
+ } else {
+ trans.info().log(text,"- Failed to Delete Approval",getId());
+ }
+ }
+ }
+
+
+ public static void resetLocalData() {
+ cache.resetLocalData();
+ }
+
+ public static int sizeForDeletion() {
+ return cache.cacheSize();
+ }
+
+ public static void delayDelete(AuthzTrans noAvg, ApprovalDAO apprDAO, boolean dryRun, List<Approval> list, String text) {
+ if(list!=null) {
+ for(Approval a : list) {
+ a.delayDelete(noAvg, apprDAO, dryRun,text);
+ }
+ }
+ }
+
+ public static boolean pendingDelete(Approval a) {
+ return cache.contains(a);
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approver.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approver.java
new file mode 100644
index 00000000..6043e436
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Approver.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.onap.aaf.auth.actions.Message;
+import org.onap.aaf.auth.org.Organization;
+
+public class Approver {
+ public String name;
+ public Organization org;
+ public Map<String, Integer> userRequests;
+
+ public Approver(String approver, Organization org) {
+ this.name = approver;
+ this.org = org;
+ userRequests = new HashMap<String, Integer>();
+ }
+
+ public void addRequest(String user) {
+ if (userRequests.get(user) == null) {
+ userRequests.put(user, 1);
+ } else {
+ Integer curCount = userRequests.remove(user);
+ userRequests.put(user, curCount+1);
+ }
+ }
+
+ /**
+ * @param sb
+ * @return
+ */
+ public void build(Message msg) {
+ msg.clear();
+ msg.line("You have %d total pending approvals from the following users:", userRequests.size());
+ for (Map.Entry<String, Integer> entry : userRequests.entrySet()) {
+ msg.line(" %s (%d)",entry.getKey(),entry.getValue());
+ }
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/CacheChange.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/CacheChange.java
new file mode 100644
index 00000000..02f34d28
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/CacheChange.java
@@ -0,0 +1,63 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CacheChange<T extends CacheChange.Data> {
+ private List<T> removed;
+
+ public CacheChange() {
+ removed = new ArrayList<T>();
+ }
+
+ interface Data {
+ public abstract void expunge();
+ }
+
+ public final void delayedDelete(T t) {
+ removed.add(t);
+ }
+
+ public final List<T> getRemoved() {
+ return removed;
+ }
+
+ public final void resetLocalData() {
+ if(removed==null || removed.isEmpty()) {
+ return;
+ }
+ for(T t : removed) {
+ t.expunge();
+ }
+ removed.clear();
+ }
+
+ public int cacheSize() {
+ return removed.size();
+ }
+
+ public boolean contains(T t) {
+ return removed.contains(t);
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Creator.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Creator.java
new file mode 100644
index 00000000..da6d558c
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Creator.java
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import com.datastax.driver.core.Row;
+
+public abstract class Creator<T> {
+ public abstract T create(Row row);
+ public abstract String select();
+
+ public String query(String where) {
+ StringBuilder sb = new StringBuilder(select());
+ if(where!=null) {
+ sb.append(" WHERE ");
+ sb.append(where);
+ }
+ sb.append(';');
+ return sb.toString();
+ }
+
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Cred.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Cred.java
new file mode 100644
index 00000000..58af03b5
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Cred.java
@@ -0,0 +1,306 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Cred {
+ public static final TreeMap<String,Cred> data = new TreeMap<String,Cred>();
+ public static final TreeMap<String,List<Cred>> byNS = new TreeMap<String,List<Cred>>();
+
+ public final String id;
+ public final List<Instance> instances;
+ public final String ns;
+
+ public Cred(String id) {
+ this.id = id;
+ instances = new ArrayList<Instance>();
+ ns=Question.domain2ns(id);
+ }
+
+ public static class Instance {
+ public final int type;
+ public final Date expires,written;
+ public final Integer other;
+
+ public Instance(int type, Date expires, Integer other, long written) {
+ this.type = type;
+ this.expires = expires;
+ this.other = other;
+ this.written = new Date(written);
+ }
+ }
+
+ public Date last(final int ... types) {
+ Date last = null;
+ for(Instance i : instances) {
+ if(types.length>0) { // filter by types, if requested
+ boolean quit = true;
+ for(int t : types) {
+ if(t==i.type) {
+ quit=false;
+ break;
+ }
+ }
+ if(quit) {
+ continue;
+ }
+ }
+ if(last==null || i.expires.after(last)) {
+ last = i.expires;
+ }
+ }
+ return last;
+ }
+
+
+ public Set<Integer> types() {
+ Set<Integer> types = new HashSet<Integer>();
+ for(Instance i : instances) {
+ types.add(i.type);
+ }
+ return types;
+ }
+
+ public static void load(Trans trans, Session session, int ... types ) {
+ load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred;",types);
+
+ }
+
+ public static void loadOneNS(Trans trans, Session session, String ns,int ... types ) {
+ load(trans, session,"select id, type, expires, other, writetime(cred) from authz.cred WHERE ns='" + ns + "';");
+ }
+
+ private static void load(Trans trans, Session session, String query, int ...types) {
+
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Read Creds", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ int type; // for filtering
+ String id;
+ tt = trans.start("Load Credentials", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ ++count;
+ row = iter.next();
+ id = row.getString(0);
+ type = row.getInt(1);
+ if(types.length>0) { // filter by types, if requested
+ boolean quit = true;
+ for(int t : types) {
+ if(t==type) {
+ quit=false;
+ break;
+ }
+ }
+ if(quit) {
+ continue;
+ }
+ }
+ Cred cred = data.get(id);
+ if(cred==null) {
+ cred = new Cred(id);
+ data.put(id, cred);
+ }
+ cred.instances.add(new Instance(type, row.getTimestamp(2), row.getInt(3), row.getLong(4)/1000));
+
+ List<Cred> lscd = byNS.get(cred.ns);
+ if(lscd==null) {
+ byNS.put(cred.ns, (lscd=new ArrayList<Cred>()));
+ }
+ boolean found = false;
+ for(Cred c : lscd) {
+ if(c.id.equals(cred.id)) {
+ found=true;
+ break;
+ }
+ }
+ if(!found) {
+ lscd.add(cred);
+ }
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",count,"creds");
+ }
+ }
+
+ /**
+ * Count entries in Cred data.
+ * Note, as opposed to other methods, need to load the whole cred table for the Types.
+ * @param numbuckets
+ * @return
+ */
+ public static CredCount count(int numbuckets) {
+ CredCount cc = new CredCount(numbuckets);
+ for(Cred c : data.values()) {
+ for (Instance ci : c.instances) {
+ cc.inc(ci.type,ci.written, ci.expires);
+ }
+ }
+ return cc;
+// String query = "select count(*) from authz.cred LIMIT 1000000;";
+// trans.info().log( "query: " + query );
+// TimeTaken tt = trans.start("Count Credentials", Env.REMOTE);
+// ResultSet results;
+// try {
+// Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
+// results = session.execute(stmt);
+// return results.one().getLong(0);
+// } finally {
+// tt.done();
+// }
+ }
+
+ public static class CredCount {
+ public int raw[];
+ public int basic_auth[];
+ public int basic_auth_256[];
+ public int cert[];
+ public int x509Added[];
+ public int x509Expired[];
+ public Date dates[];
+
+ public CredCount(int numbuckets) {
+ raw = new int[numbuckets];
+ basic_auth = new int[numbuckets];
+ basic_auth_256 = new int[numbuckets];
+ cert = new int[numbuckets];
+ x509Added = new int[numbuckets];
+ x509Expired = new int[numbuckets];
+ dates = new Date[numbuckets];
+ GregorianCalendar gc = new GregorianCalendar();
+ dates[0]=gc.getTime(); // now
+ gc.set(GregorianCalendar.DAY_OF_MONTH, 1);
+ gc.set(GregorianCalendar.HOUR, 0);
+ gc.set(GregorianCalendar.MINUTE, 0);
+ gc.set(GregorianCalendar.SECOND,0);
+ gc.set(GregorianCalendar.MILLISECOND,0);
+ gc.add(GregorianCalendar.MILLISECOND, -1); // last milli of month
+ for(int i=1;i<numbuckets;++i) {
+ dates[i] = gc.getTime();
+ gc.add(GregorianCalendar.MONTH, -1);
+ }
+
+ }
+
+ public void inc(int type, Date start, Date expires) {
+ for(int i=0;i<dates.length-1;++i) {
+ if(start.before(dates[i])) {
+ if(type==CredDAO.CERT_SHA256_RSA) {
+ if(start.after(dates[i+1])) {
+ ++x509Added[i];
+ }
+ }
+ if(expires.after(dates[i])) {
+ switch(type) {
+ case CredDAO.RAW:
+ ++raw[i];
+ break;
+ case CredDAO.BASIC_AUTH:
+ ++basic_auth[i];
+ break;
+ case CredDAO.BASIC_AUTH_SHA256:
+ ++basic_auth_256[i];
+ break;
+ case CredDAO.CERT_SHA256_RSA:
+ ++cert[i];
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ public long authCount(int idx) {
+ return basic_auth[idx]+basic_auth_256[idx];
+ }
+
+ public long x509Count(int idx) {
+ return cert[idx];
+ }
+
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(id);
+ sb.append('[');
+ for(Instance i : instances) {
+ sb.append('{');
+ sb.append(i.type);
+ sb.append(",\"");
+ sb.append(i.expires);
+ sb.append("\"}");
+ }
+ sb.append(']');
+ return sb.toString();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return id.equals(obj);
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Future.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Future.java
new file mode 100644
index 00000000..a2dc6b65
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Future.java
@@ -0,0 +1,200 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.UUID;
+
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Future implements CacheChange.Data, Comparable<Future> {
+ public static final Map<UUID,Future> data = new TreeMap<UUID,Future>();
+ public static final Map<String,List<Future>> byRole = new TreeMap<String,List<Future>>();
+
+ public final FutureDAO.Data fdd;
+ public final String role; // derived
+ private final static CacheChange<Future> cache = new CacheChange<Future>();
+
+
+ public final UUID id() {
+ return fdd.id;
+ }
+
+ public final String memo() {
+ return fdd.memo;
+ }
+
+ public final String target() {
+ return fdd.target;
+ }
+
+ public final Date start() {
+ return fdd.start;
+ }
+
+ public final Date expires() {
+ return fdd.expires;
+ }
+
+
+ public Future(UUID id, String memo, String target, Date start, Date expires, ByteBuffer construct) {
+ fdd = new FutureDAO.Data();
+ fdd.id = id;
+ fdd.memo = memo;
+ fdd.target = target;
+ fdd.start = start;
+ fdd.expires = expires;
+ fdd.construct = construct;
+ role = Approval.roleFromMemo(memo);
+ }
+
+ public static void load(Trans trans, Session session, Creator<Future> creator) {
+ trans.info().log( "query: " + creator.select() );
+ ResultSet results;
+ TimeTaken tt = trans.start("Load Futures", Env.REMOTE);
+ try {
+ Statement stmt = new SimpleStatement(creator.select());
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+
+ int count = 0;
+ tt = trans.start("Process Futures", Env.SUB);
+ try {
+ for(Row row : results.all()) {
+ ++count;
+ Future f = creator.create(row);
+ data.put(f.fdd.id,f);
+ if(f.role!=null) {
+ List<Future> lf = byRole.get(f.role);
+ if(lf==null) {
+ byRole.put(f.role,lf = new ArrayList<Future>());
+ }
+ lf.add(f);
+ }
+ }
+ } finally {
+ tt.done();
+ trans.info().log("Found",count,"Futures");
+ }
+ }
+
+ public static Creator<Future> v2_0_17 = new Creator<Future>() {
+ @Override
+ public Future create(Row row) {
+ return new Future(row.getUUID(0),row.getString(1),row.getString(2),
+ row.getTimestamp(3),row.getTimestamp(4), null);
+ }
+
+ @Override
+ public String select() {
+ return "select id,memo,target,start,expires from authz.future";
+ }
+ };
+
+ public static Creator<Future> withConstruct = new Creator<Future>() {
+ @Override
+ public String select() {
+ return "select id,memo,target,start,expires,construct from authz.future";
+ }
+
+ @Override
+ public Future create(Row row) {
+ return new Future(row.getUUID(0),row.getString(1),row.getString(2),
+ row.getTimestamp(3),row.getTimestamp(4), row.getBytes(5));
+ }
+
+ };
+
+ public Result<Void> delayedDelete(AuthzTrans trans, FutureDAO fd, boolean dryRun, String text) {
+ Result<Void> rv;
+ if(dryRun) {
+ trans.info().log(text,"- Would Delete: ",fdd.id,fdd.memo,"expiring on",Chrono.dateOnlyStamp(fdd.expires));
+ rv = Result.ok();
+ } else {
+ rv = fd.delete(trans, fdd, true); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log(text, "- Deleted:",fdd.id,fdd.memo,"expiring on",Chrono.dateOnlyStamp(fdd.expires));
+ cache.delayedDelete(this);
+ } else {
+ if(rv.status!=6) {
+ trans.info().log(text,"- Failed to Delete Future", fdd.id);
+ }
+ }
+ }
+ return rv;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.helpers.CacheChange.Data#resetLocalData()
+ */
+ @Override
+ public void expunge() {
+ data.remove(fdd.id);
+ if(role!=null) {
+ List<Future> lf = byRole.get(role);
+ if(lf!=null) {
+ lf.remove(this);
+ }
+ }
+ }
+
+ @Override
+ public int compareTo(Future o) {
+ if(o==null) {
+ return -1;
+ }
+ return fdd.id.compareTo(o.fdd.id);
+ }
+
+ public static void resetLocalData() {
+ cache.resetLocalData();
+ }
+
+ public static int sizeForDeletion() {
+ return cache.cacheSize();
+ }
+
+ public static boolean pendingDelete(Future f) {
+ return cache.contains(f);
+ }
+
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/History.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/History.java
new file mode 100644
index 00000000..f153c06b
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/History.java
@@ -0,0 +1,178 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.UUID;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class History {
+ public final UUID id;
+ public final String action;
+ public final String memo;
+ public final String reconstruct;
+ public final String subject;
+ public final String target;
+ public final String user;
+ public final int yr_mon;
+
+ public History(UUID id, String action, String memo, String subject, String target, String user, int yr_mon) {
+ this.id = id;
+ this.action = action;
+ this.memo = memo;
+ this.reconstruct = null;
+ this.subject = subject;
+ this.target = target;
+ this.user = user;
+ this.yr_mon = yr_mon;
+ }
+
+ public History(UUID id, String action, String memo, String reconstruct, String subject, String target, String user, int yr_mon) {
+ this.id = id;
+ this.action = action;
+ this.memo = memo;
+ this.reconstruct = reconstruct;
+ this.subject = subject;
+ this.target = target;
+ this.user = user;
+ this.yr_mon = yr_mon;
+ }
+
+ public static void load(Trans trans, Session session, Creator<History> creator, Loader<History> loader) {
+ trans.info().log( "query: " + creator.select() );
+ TimeTaken tt = trans.start("Read History", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( creator.select() ).setReadTimeoutMillis(240000);
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load History", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ ++count;
+ row = iter.next();
+ loader.exec(creator.create(row));
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",count,"histories");
+ }
+ }
+
+ public String toString() {
+ return String.format("%s %d %s, %s, %s, %s, %s",
+ id.toString(),
+ yr_mon,
+ user,
+ target,
+ action,
+ subject,
+ memo);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return id.equals(obj);
+ }
+
+ public static Creator<History> sansConstruct = new Creator<History> () {
+ @Override
+ public History create(Row row) {
+ return new History(
+ row.getUUID(0),
+ row.getString(1),
+ row.getString(2),
+ row.getString(3),
+ row.getString(4),
+ row.getString(5),
+ row.getInt(6));
+ }
+
+ @Override
+ public String select() {
+ return "SELECT id, action, memo, subject, target, user, yr_mon from authz.history LIMIT 10000000 ";
+ }
+ };
+
+ public static Creator<History> avecConstruct = new Creator<History> () {
+ private final StringBuilder sb = new StringBuilder();
+
+ @Override
+ public History create(Row row) {
+ ByteBuffer bb = row.getBytes(3);
+ sb.setLength(0);
+
+ if(bb!=null && bb.hasRemaining()) {
+ sb.append("0x");
+ while(bb.hasRemaining()) {
+ sb.append(String.format("%02x",bb.get()));
+ }
+ bb.flip();
+ }
+ return new History(
+ row.getUUID(0),
+ row.getString(1),
+ row.getString(2),
+ sb.toString(),
+ row.getString(4),
+ row.getString(5),
+ row.getString(6),
+ row.getInt(7));
+ }
+
+ @Override
+ public String select() {
+ return "SELECT id, action, memo, reconstruct, subject, target, user, yr_mon from authz.history LIMIT 10000000 ";
+ }
+ };
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/InputIterator.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/InputIterator.java
new file mode 100644
index 00000000..cb0bfa6a
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/InputIterator.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Iterator;
+
+public class InputIterator implements Iterable<String> {
+ private BufferedReader in;
+ private final PrintStream out;
+ private final String prompt, instructions;
+
+ public InputIterator(BufferedReader in, PrintStream out, String prompt, String instructions) {
+ this.in = in;
+ this.out = out;
+ this.prompt = prompt;
+ this.instructions = instructions;
+ }
+
+ @Override
+ public Iterator<String> iterator() {
+ out.println(instructions);
+ return new Iterator<String>() {
+ String input;
+ @Override
+ public boolean hasNext() {
+ out.append(prompt);
+ try {
+ input = in.readLine();
+ } catch (IOException e) {
+ input = null;
+ return false;
+ }
+ return input.length()>0;
+ }
+
+ @Override
+ public String next() {
+ return input;
+ }
+
+ @Override
+ public void remove() {
+ }
+ };
+ }
+}
+
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Loader.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Loader.java
new file mode 100644
index 00000000..6d27f648
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Loader.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+public interface Loader<T> {
+ public void exec(T t);
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MiscID.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MiscID.java
new file mode 100644
index 00000000..1438ffdb
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MiscID.java
@@ -0,0 +1,188 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.aaf.auth.BatchException;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class MiscID {
+ public static final TreeMap<String,MiscID> data = new TreeMap<String,MiscID>();
+ /*
+ Sample Record
+ aad890|mj9030|20040902|20120207
+
+ **** Field Definitions ****
+ MISCID - AT&T Miscellaneous ID - Non-User ID (Types: Internal Mechanized ID, External Mechanized ID, Datagate ID, Customer ID, Vendor ID, Exchange Mail ID, CLEC ID, Specialized ID, Training ID)
+ SPONSOR_ATTUID - ATTUID of MiscID Sponsor (Owner)
+ CREATE_DATE - Date when MiscID was created
+ LAST_RENEWAL_DATE - Date when MiscID Sponsorship was last renewed
+ */
+ public String id,sponsor,created,renewal;
+
+ private static final String fieldString = "id,created,sponsor,renewal";
+
+ /**
+ * Load a Row of Strings (from CSV file).
+ *
+ * Be CAREFUL that the Row lists match the Fields above!!! If this changes, change
+ * 1) This Object
+ * 2) DB "suits.cql"
+ * 3) Alter existing Tables
+ * @param row
+ * @throws BatchException
+ * @throws IllegalAccessException
+ * @throws IllegalArgumentException
+ */
+ public void set(String row []) throws BatchException {
+ if(row.length<4) {throw new BatchException("Row of MiscID_XRef is too short");}
+ id = row[0];
+ sponsor = row[1];
+ created = row[2];
+ renewal = row[3];
+ }
+
+ public void set(Row row) {
+ id = row.getString(0);
+ sponsor = row.getString(1);
+ created = row.getString(2);
+ renewal = row.getString(3);
+ }
+
+
+ public static void load(Trans trans, Session session ) {
+ load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",data);
+ }
+
+ public static void load(Trans trans, Session session, Map<String,MiscID> map ) {
+ load(trans, session,"SELECT " + fieldString + " FROM authz.miscid;",map);
+ }
+
+ public static void loadOne(Trans trans, Session session, String id ) {
+ load(trans, session,"SELECT " + fieldString + " FROM authz.miscid WHERE id ='" + id + "';", data);
+ }
+
+ public static void load(Trans trans, Session session, String query, Map<String,MiscID> map) {
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Read MiscID", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ try {
+ tt = trans.start("Load Map", Env.SUB);
+ try {
+ for( Row row : results.all()) {
+ MiscID miscID = new MiscID();
+ miscID.set(row);
+ data.put(miscID.id,miscID);
+ ++count;
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",count,"miscID records");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return id.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if(obj!=null && obj instanceof MiscID) {
+ return id.equals(((MiscID)obj).id);
+ }
+ return false;
+ }
+
+ public StringBuilder insertStmt() throws IllegalArgumentException, IllegalAccessException {
+ StringBuilder sb = new StringBuilder("INSERT INTO authz.miscid (");
+ sb.append(fieldString);
+ sb.append(") VALUES ('");
+ sb.append(id);
+ sb.append("','");
+ sb.append(sponsor);
+ sb.append("','");
+ sb.append(created);
+ sb.append("','");
+ sb.append(renewal);
+ sb.append("')");
+ return sb;
+ }
+
+ public StringBuilder updateStmt(MiscID source) {
+ StringBuilder sb = null;
+ if(id.equals(source.id)) {
+ sb = addField(sb,"sponser",sponsor,source.sponsor);
+ sb = addField(sb,"created",created,source.created);
+ sb = addField(sb,"renewal",renewal,source.renewal);
+ }
+ if(sb!=null) {
+ sb.append(" WHERE id='");
+ sb.append(id);
+ sb.append('\'');
+ }
+ return sb;
+ }
+
+ private StringBuilder addField(StringBuilder sb, String name, String a, String b) {
+ if(!a.equals(b)) {
+ if(sb==null) {
+ sb = new StringBuilder("UPDATE authz.miscid SET ");
+ } else {
+ sb.append(',');
+ }
+ sb.append(name);
+ sb.append("='");
+ sb.append(b);
+ sb.append('\'');
+ }
+ return sb;
+ }
+
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MonthData.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MonthData.java
new file mode 100644
index 00000000..13a4c923
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/MonthData.java
@@ -0,0 +1,121 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.aaf.misc.env.util.Split;
+
+import java.util.Set;
+import java.util.TreeMap;
+
+public class MonthData {
+ public final Map<Integer,Set<Row>> data =
+ new TreeMap<Integer,Set<Row>>();
+ private File f;
+
+ public MonthData(String env) throws IOException {
+ f = new File("Monthly"+env+".dat");
+
+ if(f.exists()) {
+ BufferedReader br = new BufferedReader(new FileReader(f));
+ try {
+ String line;
+ String[] split;
+ while((line=br.readLine())!=null) {
+ if(!line.startsWith("#")) {
+ split = Split.split(',', line);
+ if(split.length==5) {
+ add(Integer.parseInt(split[0]),split[1],
+ Integer.parseInt(split[2]),
+ Integer.parseInt(split[3]),
+ Integer.parseInt(split[4])
+ );
+ }
+ }
+ }
+ } finally {
+ br.close();
+ }
+ }
+ }
+
+ public void add(int yr_mon, String target, long total, long adds, long drops) {
+ Set<Row> row = data.get(yr_mon);
+ if(row==null) {
+ data.put(yr_mon, (row=new HashSet<Row>()));
+ }
+ row.add(new Row(target,total,adds,drops));
+ }
+
+ public boolean notExists(int yr_mon) {
+ return data.get(yr_mon)==null;
+ }
+
+ public static class Row implements Comparable<Row> {
+ public final String target;
+ public final long total;
+ public final long adds;
+ public final long drops;
+
+ public Row(String t, long it, long a, long d) {
+ target = t;
+ total = it;
+ adds = a;
+ drops = d;
+ }
+
+ @Override
+ public int compareTo(Row o) {
+ return target.compareTo(o.target);
+ }
+
+ public String toString() {
+ return target + '|' + total + '|' + drops + '|' + adds;
+ }
+ }
+
+ public void write() throws IOException {
+ if(f.exists()) {
+ File bu = new File(f.getName()+".bak");
+ f.renameTo(bu);
+ }
+ PrintStream ps = new PrintStream(f);
+ try {
+ for( Entry<Integer, Set<Row>> rows : data.entrySet()) {
+ for(Row row : rows.getValue()) {
+ ps.printf("%d,%s,%d,%d,%d\n",rows.getKey(),row.target,row.total,row.adds,row.drops);
+ }
+ }
+ } finally {
+ ps.close();
+ }
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NS.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NS.java
new file mode 100644
index 00000000..5dde8895
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NS.java
@@ -0,0 +1,168 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class NS implements Comparable<NS> {
+ public final static Map<String,NS> data = new TreeMap<String,NS>();
+
+ public final String name, description, parent;
+ public final int scope,type;
+
+ public NS(String name, String description, String parent, int type, int scope) {
+ this.name = name;
+ this.description = description;
+ this.parent = parent;
+ this.scope = scope;
+ this.type = type;
+ }
+
+ public static void load(Trans trans, Session session, Creator<NS> creator) {
+ load(trans,session,
+ "select name, description, parent, type, scope from authz.ns;"
+ ,creator);
+ }
+
+ public static void loadOne(Trans trans, Session session, Creator<NS> creator, String ns) {
+ load(trans,session,
+ ("select name, description, parent, type, scope from authz.ns WHERE name='"+ns+"';")
+ ,creator
+ );
+ }
+
+ private static void load(Trans trans, Session session, String query, Creator<NS> creator) {
+ trans.info().log( "query: " + query );
+ ResultSet results;
+ TimeTaken tt;
+
+ tt = trans.start("Read Namespaces", Env.REMOTE);
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+
+
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load Namespaces", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ row = iter.next();
+ NS ns = creator.create(row);
+ data.put(ns.name,ns);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",data.size(),"Namespaces");
+ }
+
+ }
+
+ public static long count(Trans trans, Session session) {
+ String query = "select count(*) from authz.ns LIMIT 1000000;";
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
+ results = session.execute(stmt);
+ return results.one().getLong(0);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return name.equals(obj);
+ }
+
+ @Override
+ public int compareTo(NS o) {
+ return name.compareTo(o.name);
+ }
+
+ public static class NSSplit {
+ public String ns;
+ public String other;
+ public NSSplit(String s, int dot) {
+ ns = s.substring(0,dot);
+ other = s.substring(dot+1);
+ }
+ }
+ public static NSSplit deriveParent(String dotted) {
+ if(dotted==null)return null;
+ for(int idx = dotted.lastIndexOf('.');idx>=0; idx=dotted.lastIndexOf('.',idx-1)) {
+ if(data.get(dotted.substring(0, idx))!=null) {
+ return new NSSplit(dotted,idx);
+ }
+ }
+ return null;
+ }
+
+ public static Creator<NS> v2_0_11 = new Creator<NS> () {
+ @Override
+ public NS create(Row row) {
+ return new NS(row.getString(0),row.getString(1), row.getString(2),row.getInt(3),row.getInt(4));
+ }
+
+ @Override
+ public String select() {
+ return "SELECT name, description, parent, type, scope FROM authz.ns ";
+ }
+ };
+
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Notification.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Notification.java
new file mode 100644
index 00000000..9614bb19
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Notification.java
@@ -0,0 +1,209 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.onap.aaf.auth.actions.Message;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Notification {
+ public enum TYPE {
+ OA("Owner Approval",1),SA("Supervisor Approval",2),CN("Credential Expiration",20);
+
+ private String desc;
+ private int type;
+
+ private TYPE(String desc,int type) {
+ this.desc = desc;
+ this.type = type;
+ }
+
+ public String desc() {
+ return desc;
+ }
+
+ public int idx() {
+ return type;
+ }
+
+ public static TYPE get(int idx) {
+ for(TYPE nt : TYPE.values()) {
+ if(idx==nt.type) {
+ return nt;
+ }
+ }
+ return null;
+ }
+ }
+
+
+ public static final TreeMap<String,List<Notification>> data = new TreeMap<String,List<Notification>>();
+ public static final Date now = new Date();
+
+ public final String user;
+ public final TYPE type;
+ public Date last;
+ public int checksum;
+ public Message msg;
+ private int current;
+ public Organization org;
+ public int count;
+
+ private Notification(String user, TYPE nt, Date last, int checksum) {
+ this.user = user;
+ this.type = nt;
+ this.last = last;
+ this.checksum = checksum;
+ current = 0;
+ count = 0;
+ }
+
+ public static void load(Trans trans, Session session, Creator<Notification> creator ) {
+ trans.info().log( "query: " + creator.select() );
+ TimeTaken tt = trans.start("Load Notify", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(creator.select());
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ tt = trans.start("Process Notify", Env.SUB);
+
+ try {
+ for(Row row : results.all()) {
+ ++count;
+ try {
+ Notification not = creator.create(row);
+ List<Notification> ln = data.get(not.user);
+ if(ln==null) {
+ ln = new ArrayList<Notification>();
+ data.put(not.user, ln);
+ }
+ ln.add(not);
+ } finally {
+ tt.done();
+ }
+ }
+ } finally {
+ tt.done();
+ trans.info().log("Found",count,"Notify Records");
+ }
+ }
+
+ public static Notification get(String user, TYPE type) {
+ List<Notification> ln = data.get(user);
+ if(ln!=null) {
+ for(Notification n : ln) {
+ if(type.equals(n.type)) {
+ return n;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static Notification create(String user, TYPE type) {
+ return new Notification(user,type,null,0);
+ }
+
+ public static Creator<Notification> v2_0_18 = new Creator<Notification>() {
+ @Override
+ public Notification create(Row row) {
+ int idx =row.getInt(1);
+ TYPE type = TYPE.get(idx);
+ if(type==null) {
+ return null;
+ }
+ return new Notification(row.getString(0), type, row.getTimestamp(2), row.getInt(3));
+ }
+
+ @Override
+ public String select() {
+ return "SELECT user,type,last,checksum FROM authz.notify LIMIT 100000";
+ }
+ };
+
+
+ public void set(Message msg) {
+ this.msg = msg;
+ }
+
+ public int checksum() {
+ if(msg==null) {
+ current=0;
+ } else if(current==0) {
+ for(String l : msg.lines) {
+ for(byte b : l.getBytes()) {
+ current+=b;
+ }
+ }
+ }
+ return current;
+ }
+
+ public boolean update(AuthzTrans trans, Session session, boolean dryRun) {
+ checksum();
+ if(last==null || current==0 || current!=checksum) {
+ last = now;
+ current = checksum();
+ String update = "UPDATE authz.notify SET " +
+ "last = '" + Chrono.utcStamp(last) +
+ "', checksum=" +
+ current +
+ " WHERE user='" +
+ user +
+ "' AND type=" +
+ type.idx() +
+ ";";
+ if(dryRun) {
+ trans.info().log("Would",update);
+ } else {
+ session.execute(update);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public String toString() {
+ return "\"" + user + "\",\"" + type.name() + "\",\""
+ + Chrono.dateTime(last)+ "\", " + checksum;
+ }
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NsAttrib.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NsAttrib.java
new file mode 100644
index 00000000..bb76c34c
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/NsAttrib.java
@@ -0,0 +1,107 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class NsAttrib {
+ public static final List<NsAttrib> data = new ArrayList<NsAttrib>();
+ public static final TreeMap<String,List<NsAttrib>> byKey = new TreeMap<String,List<NsAttrib>>();
+ public static final TreeMap<String,List<NsAttrib>> byNS = new TreeMap<String,List<NsAttrib>>();
+
+ public final String ns,key,value;
+
+ public NsAttrib(String ns, String key, String value) {
+ this.ns = ns;
+ this.key = key;
+ this.value = value;
+ }
+
+ public static void load(Trans trans, Session session, Creator<NsAttrib> creator ) {
+ trans.info().log( "query: " + creator.select() );
+ ResultSet results;
+ TimeTaken tt = trans.start("Load NsAttributes", Env.REMOTE);
+ try {
+ Statement stmt = new SimpleStatement(creator.select());
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ int count = 0;
+ tt = trans.start("Process NsAttributes", Env.SUB);
+
+ try {
+ for(Row row : results.all()) {
+ ++count;
+ NsAttrib ur = creator.create(row);
+ data.add(ur);
+
+ List<NsAttrib> lna = byKey.get(ur.key);
+ if(lna==null) {
+ lna = new ArrayList<NsAttrib>();
+ byKey.put(ur.key, lna);
+ }
+ lna.add(ur);
+
+ lna = byNS.get(ur.ns);
+ if(lna==null) {
+ lna = new ArrayList<NsAttrib>();
+ byNS.put(ur.ns, lna);
+ }
+ lna.add(ur);
+ }
+ } finally {
+ tt.done();
+ trans.info().log("Found",count,"NS Attributes");
+ }
+ }
+
+ public static Creator<NsAttrib> v2_0_11 = new Creator<NsAttrib>() {
+ @Override
+ public NsAttrib create(Row row) {
+ return new NsAttrib(row.getString(0), row.getString(1), row.getString(2));
+ }
+
+ @Override
+ public String select() {
+ return "select ns,key,value from authz.ns_attrib";
+ }
+ };
+
+
+ public String toString() {
+ return '"' + ns + "\",\"" + key + "\",\"" + value +'"';
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Perm.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Perm.java
new file mode 100644
index 00000000..51a7098e
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Perm.java
@@ -0,0 +1,172 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Perm implements Comparable<Perm> {
+ public static final TreeMap<Perm,Set<String>> data = new TreeMap<Perm,Set<String>>();
+ public static final TreeMap<String,Perm> keys = new TreeMap<String,Perm>();
+ private static List<Perm> deletePerms = new ArrayList<Perm>();
+
+ public final String ns, type, instance, action,description;
+ private String fullType = null, fullPerm = null, encode = null;
+ public final Set<String> roles;
+
+ public String encode() {
+ if(encode == null) {
+ encode = ns + '|' + type + '|' + instance + '|' + action;
+ }
+ return encode;
+ }
+
+ public String fullType() {
+ if(fullType==null) {
+ fullType = ns + '.' + type;
+ }
+ return fullType;
+ }
+
+ public String fullPerm() {
+ if(fullPerm==null) {
+ fullPerm = ns + '.' + type + '|' + instance + '|' + action;
+ }
+ return fullPerm;
+ }
+
+ public Perm(String ns, String type, String instance, String action, String description, Set<String> roles) {
+ this.ns = ns;
+ this.type = type;
+ this.instance = instance;
+ this.action = action;
+ this.description = description;
+ // 2.0.11
+// this.full = encode();//ns+'.'+type+'|'+instance+'|'+action;
+ this.roles = roles;
+ }
+
+ public static void load(Trans trans, Session session) {
+ load(trans, session, "select ns, type, instance, action, description, roles from authz.perm;");
+ }
+
+ public static void loadOneNS(Trans trans, Session session, String ns) {
+ load(trans, session, "select ns, type, instance, action, description, roles from authz.perm WHERE ns='" + ns + "';");
+
+ }
+
+ private static void load(Trans trans, Session session, String query) {
+ //
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Read Perms", Env.REMOTE);
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load Perms", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ row = iter.next();
+ Perm pk = new Perm(row.getString(0),row.getString(1),row.getString(2),row.getString(3), row.getString(4), row.getSet(5,String.class));
+ keys.put(pk.encode(), pk);
+ data.put(pk,pk.roles);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",data.size(),"perms");
+ }
+ }
+
+ public static long count(Trans trans, Session session) {
+ String query = "select count(*) from authz.perm LIMIT 1000000;";
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
+ results = session.execute(stmt);
+ return results.one().getLong(0);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public String toString() {
+ return encode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return encode().hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return encode().equals(obj);
+ }
+
+ @Override
+ public int compareTo(Perm o) {
+ return encode().compareTo(o.encode());
+ }
+
+ public static void stageRemove(Perm p) {
+ deletePerms.add(p);
+ }
+
+ public static void executeRemove() {
+ for(Perm p : deletePerms) {
+ keys.remove(p.encode);
+ data.remove(p);
+ }
+ deletePerms.clear();
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Role.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Role.java
new file mode 100644
index 00000000..f48544b1
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/Role.java
@@ -0,0 +1,175 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class Role implements Comparable<Role> {
+ public static final TreeMap<Role,Set<String>> data = new TreeMap<Role,Set<String>>();
+ public static final TreeMap<String,Role> keys = new TreeMap<String,Role>();
+ public static final TreeMap<String,Role> byName = new TreeMap<String,Role>();
+ private static List<Role> deleteRoles = new ArrayList<Role>();
+
+ public final String ns, name, description;
+ private String full, encode;
+ public final Set<String> perms;
+
+ public Role(String full) {
+ ns = name = description = "";
+ this.full = full;
+ perms = new HashSet<String>();
+ }
+
+ public Role(String ns, String name, String description,Set<String> perms) {
+ this.ns = ns;
+ this.name = name;
+ this.description = description;
+ this.full = null;
+ this.encode = null;
+ this.perms = perms;
+ }
+
+ public String encode() {
+ if(encode==null) {
+ encode = ns + '|' + name;
+ }
+ return encode;
+ }
+
+ public String fullName() {
+ if(full==null) {
+ full = ns + '.' + name;
+ }
+ return full;
+ }
+
+ public static void load(Trans trans, Session session ) {
+ load(trans,session,"select ns, name, description, perms from authz.role;");
+ }
+
+ public static void loadOneNS(Trans trans, Session session, String ns ) {
+ load(trans,session,"select ns, name, description, perms from authz.role WHERE ns='" + ns + "';");
+ }
+
+ private static void load(Trans trans, Session session, String query) {
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Read Roles", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load Roles", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ row = iter.next();
+ Role rk =new Role(row.getString(0),row.getString(1), row.getString(2),row.getSet(3,String.class));
+ keys.put(rk.encode(), rk);
+ data.put(rk,rk.perms);
+ byName.put(rk.fullName(), rk);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",data.size(),"roles");
+ }
+ }
+
+ public static long count(Trans trans, Session session) {
+ String query = "select count(*) from authz.role LIMIT 1000000;";
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
+ results = session.execute(stmt);
+ return results.one().getLong(0);
+ } finally {
+ tt.done();
+ }
+ }
+
+ public String toString() {
+ return encode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return encode().hashCode();
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return encode().equals(obj);
+ }
+
+ @Override
+ public int compareTo(Role o) {
+ return encode().compareTo(o.encode());
+ }
+
+ public static String fullName(String role) {
+ return role.replace('|', '.');
+ }
+
+ public static void stageRemove(Role r) {
+ deleteRoles.add(r);
+ }
+
+ public static void executeRemove() {
+ for(Role p : deleteRoles) {
+ keys.remove(p.encode);
+ data.remove(p);
+ }
+ deleteRoles.clear();
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java
new file mode 100644
index 00000000..d990bb11
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/helpers/UserRole.java
@@ -0,0 +1,282 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.helpers;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.onap.aaf.auth.actions.URDelete;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO;
+import org.onap.aaf.auth.dao.cass.UserRoleDAO.Data;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.util.Chrono;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.Session;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class UserRole implements Cloneable, CacheChange.Data {
+ public static final List<UserRole> data = new ArrayList<UserRole>();
+ public static final TreeMap<String,List<UserRole>> byUser = new TreeMap<String,List<UserRole>>();
+ public static final TreeMap<String,List<UserRole>> byRole = new TreeMap<String,List<UserRole>>();
+ private final static CacheChange<UserRole> cache = new CacheChange<UserRole>();
+ private static PrintStream urDelete=System.out,urRecover=System.err;
+ private static int totalLoaded;
+ private static int deleted;
+
+ private Data urdd;
+
+ public UserRole(String user, String ns, String rname, Date expires) {
+ urdd = new UserRoleDAO.Data();
+ urdd.user = user;
+ urdd.role = ns + '.' + rname;
+ urdd.ns = ns;
+ urdd.rname = rname;
+ urdd.expires = expires;
+ }
+
+ public UserRole(String user, String role, String ns, String rname, Date expires) {
+ urdd = new UserRoleDAO.Data();
+ urdd.user = user;
+ urdd.role = role;
+ urdd.ns = ns;
+ urdd.rname = rname;
+ urdd.expires = expires;
+ }
+
+ public static void load(Trans trans, Session session, Creator<UserRole> creator ) {
+ load(trans,session,creator,null);
+ }
+
+ public static void loadOneRole(Trans trans, Session session, Creator<UserRole> creator, String role) {
+ load(trans,session,creator,"role='" + role +"' ALLOW FILTERING;");
+ }
+
+ public static void loadOneUser(Trans trans, Session session, Creator<UserRole> creator, String user ) {
+ load(trans,session,creator,"role='"+ user +"';");
+ }
+
+ private static void load(Trans trans, Session session, Creator<UserRole> creator, String where) {
+ String query = creator.query(where);
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Read UserRoles", Env.REMOTE);
+
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement( query );
+ results = session.execute(stmt);
+ } finally {
+ tt.done();
+ }
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load UserRole", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ ++totalLoaded;
+ row = iter.next();
+ UserRole ur = creator.create(row);
+ data.add(ur);
+
+ List<UserRole> lur = byUser.get(ur.urdd.user);
+ if(lur==null) {
+ lur = new ArrayList<UserRole>();
+ byUser.put(ur.urdd.user, lur);
+ }
+ lur.add(ur);
+
+ lur = byRole.get(ur.urdd.role);
+ if(lur==null) {
+ lur = new ArrayList<UserRole>();
+ byRole.put(ur.urdd.role, lur);
+ }
+ lur.add(ur);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Loaded",totalLoaded,"UserRoles");
+ }
+ }
+
+ public int totalLoaded() {
+ return totalLoaded();
+ }
+
+ public int deleted() {
+ return deleted;
+ }
+
+ @Override
+ public void expunge() {
+ data.remove(this);
+
+ List<UserRole> lur = byUser.get(urdd.user);
+ if(lur!=null) {
+ lur.remove(this);
+ }
+
+ lur = byRole.get(urdd.role);
+ if(lur!=null) {
+ lur.remove(this);
+ }
+ }
+
+ public static void setDeleteStream(PrintStream ds) {
+ urDelete = ds;
+ }
+
+ public static void setRecoverStream(PrintStream ds) {
+ urRecover = ds;
+ }
+
+ public static long count(Trans trans, Session session) {
+ String query = "select count(*) from authz.user_role LIMIT 1000000;";
+ trans.info().log( "query: " + query );
+ TimeTaken tt = trans.start("Count Namespaces", Env.REMOTE);
+ ResultSet results;
+ try {
+ Statement stmt = new SimpleStatement(query).setReadTimeoutMillis(12000);
+ results = session.execute(stmt);
+ return results.one().getLong(0);
+ } finally {
+ tt.done();
+ }
+ }
+
+
+ public static Creator<UserRole> v2_0_11 = new Creator<UserRole>() {
+ @Override
+ public UserRole create(Row row) {
+ return new UserRole(row.getString(0), row.getString(1), row.getString(2),row.getString(3),row.getTimestamp(4));
+ }
+
+ @Override
+ public String select() {
+ return "select user,role,ns,rname,expires from authz.user_role";
+ }
+ };
+
+ public UserRoleDAO.Data urdd() {
+ return urdd;
+ }
+
+ public String user() {
+ return urdd.user;
+ };
+
+ public String role() {
+ return urdd.role;
+ }
+
+ public String ns() {
+ return urdd.ns;
+ }
+
+ public String rname() {
+ return urdd.rname;
+ }
+
+ public Date expires() {
+ return urdd.expires;
+ }
+
+ public void expires(Date time) {
+ urdd.expires = time;
+ }
+
+
+
+ public String toString() {
+ return "\"" + urdd.user + "\",\"" + urdd.role + "\",\"" + urdd.ns + "\",\"" + urdd.rname + "\",\""+ Chrono.dateOnlyStamp(urdd.expires);
+ }
+
+ public static UserRole get(String u, String r) {
+ List<UserRole> lur = byUser.get(u);
+ if(lur!=null) {
+ for(UserRole ur : lur) {
+ if(ur.urdd.role.equals(r)) {
+ return ur;
+ }
+ }
+ }
+ return null;
+ }
+
+ // CACHE Calling
+ private static final String logfmt = "%s UserRole - %s: %s-%s (%s, %s) expiring %s";
+ private static final String replayfmt = "%s|%s|%s|%s|%s\n";
+ private static final String deletefmt = "# %s\n"+replayfmt;
+
+ // SAFETY - DO NOT DELETE USER ROLES DIRECTLY FROM BATCH FILES!!!
+ // We write to a file, and validate. If the size is iffy, we email Support
+ public void delayDelete(AuthzTrans trans, String text, boolean dryRun) {
+ String dt = Chrono.dateTime(urdd.expires);
+ if(dryRun) {
+ trans.info().printf(logfmt,text,"Would Delete",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
+ } else {
+ trans.info().printf(logfmt,text,"Staged Deletion",urdd.user,urdd.role,urdd.ns,urdd.rname,dt);
+ }
+ urDelete.printf(deletefmt,text,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
+ urRecover.printf(replayfmt,urdd.user,urdd.role,dt,urdd.ns,urdd.rname);
+
+ cache.delayedDelete(this);
+ ++deleted;
+ }
+
+
+ /**
+ * Calls expunge() for all deleteCached entries
+ */
+ public static void resetLocalData() {
+ cache.resetLocalData();
+ }
+
+ public static int sizeForDeletion() {
+ return cache.cacheSize();
+ }
+
+ public static boolean pendingDelete(UserRole ur) {
+ return cache.contains(ur);
+ }
+
+ public static void actuateDeletionNow(AuthzTrans trans, URDelete directDel) {
+ for(UserRole ur : cache.getRemoved()) {
+ directDel.exec(trans, ur, "Actuating UserRole Deletion");
+ }
+ cache.getRemoved().clear();
+ cache.resetLocalData();
+ }
+
+
+} \ No newline at end of file
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java
new file mode 100644
index 00000000..2412f496
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/reports/ExpiringNext.java
@@ -0,0 +1,143 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.reports;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.onap.aaf.auth.Batch;
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Cred;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.helpers.Cred.Instance;
+import org.onap.aaf.auth.org.OrganizationException;
+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.util.Chrono;
+
+public class ExpiringNext extends Batch {
+
+ public ExpiringNext(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+ trans.info().log("Starting Connection Process");
+
+ TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
+ try {
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+
+ UserRole.load(trans, session, UserRole.v2_0_11);
+ Cred.load(trans, session);
+ } finally {
+ tt0.done();
+ }
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ GregorianCalendar gc = new GregorianCalendar();
+ Date now = gc.getTime();
+ gc.add(GregorianCalendar.WEEK_OF_MONTH, 2);
+ Date twoWeeks = gc.getTime();
+ // Set time way off
+ gc.set(GregorianCalendar.YEAR, 3000);
+ Date earliestUR = gc.getTime();
+ Date earliestCred = gc.getTime();
+ // Run for Roles
+ List<String> expiring = new ArrayList<String>();
+
+ trans.info().log("Checking for Expired UserRoles");
+ for(UserRole ur : UserRole.data) {
+ if(ur.expires().after(now)) {
+ if(ur.expires().before(twoWeeks)) {
+ expiring.add(Chrono.dateOnlyStamp(ur.expires()) + ":\t" + ur.user() + '\t' + ur.role());
+ }
+ if(ur.expires().before(earliestUR)) {
+ earliestUR = ur.expires();
+ }
+ }
+ }
+
+ if(expiring.size()>0) {
+ Collections.sort(expiring,Collections.reverseOrder());
+ for(String s : expiring) {
+ System.err.print('\t');
+ System.err.println(s);
+ }
+ trans.info().printf("Earliest Expiring UR is %s\n\n", Chrono.dateOnlyStamp(earliestUR));
+ } else {
+ trans.info().printf("No Expiring UserRoles within 2 weeks");
+ }
+
+ expiring.clear();
+
+ trans.info().log("Checking for Expired Credentials");
+ for( Cred creds : Cred.data.values()) {
+ Instance lastInstance=null;
+ for(Instance inst : creds.instances) {
+ if(inst.type==CredDAO.BASIC_AUTH || inst.type==CredDAO.BASIC_AUTH_SHA256) {
+ if(lastInstance == null || inst.expires.after(lastInstance.expires)) {
+ lastInstance = inst;
+ }
+ }
+ }
+ if(lastInstance!=null) {
+ if(lastInstance.expires.after(now)) {
+ if(lastInstance.expires.before(twoWeeks)) {
+ expiring.add(Chrono.dateOnlyStamp(lastInstance.expires) + ": \t" + creds.id);
+ }
+ }
+ if(lastInstance.expires.before(earliestCred)) {
+ earliestCred = lastInstance.expires;
+ }
+ }
+ }
+
+ if(expiring.size()>0) {
+ Collections.sort(expiring,Collections.reverseOrder());
+ for(String s : expiring) {
+ System.err.print('\t');
+ System.err.println(s);
+ }
+ trans.info().printf("Earliest Expiring Cred is %s\n\n", Chrono.dateOnlyStamp(earliestCred));
+ } else {
+ trans.info().printf("No Expiring Creds within 2 weeks");
+ }
+
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java
new file mode 100644
index 00000000..d3b80d21
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/Expiring.java
@@ -0,0 +1,503 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.update;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.UUID;
+
+import org.onap.aaf.auth.Batch;
+import org.onap.aaf.auth.BatchPrincipal;
+import org.onap.aaf.auth.actions.Action;
+import org.onap.aaf.auth.actions.ActionDAO;
+import org.onap.aaf.auth.actions.CacheTouch;
+import org.onap.aaf.auth.actions.CredDelete;
+import org.onap.aaf.auth.actions.CredPrint;
+import org.onap.aaf.auth.actions.Email;
+import org.onap.aaf.auth.actions.Message;
+import org.onap.aaf.auth.actions.URDelete;
+import org.onap.aaf.auth.actions.URFutureApprove;
+import org.onap.aaf.auth.actions.URFutureApproveExec;
+import org.onap.aaf.auth.actions.URPrint;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.hl.Function.FUTURE_OP;
+import org.onap.aaf.auth.dao.hl.Function.OP_STATUS;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Approval;
+import org.onap.aaf.auth.helpers.Cred;
+import org.onap.aaf.auth.helpers.Future;
+import org.onap.aaf.auth.helpers.NS;
+import org.onap.aaf.auth.helpers.Role;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.helpers.Cred.Instance;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.Organization.Identity;
+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.util.Chrono;
+
+public class Expiring extends Batch {
+ private CredPrint crPrint;
+ private URFutureApprove urFutureApprove;
+ private URFutureApproveExec urFutureApproveExec;
+ private CredDelete crDelete;
+ private URDelete urDelete;
+ private final CacheTouch cacheTouch;
+ private final AuthzTrans noAvg;
+ private final ApprovalDAO apprDAO;
+ private final FutureDAO futureDAO;
+ private final PrintStream urDeleteF,urRecoverF;
+ private final URPrint urPrint;
+ private Email email;
+ private File deletesFile;
+
+ public Expiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+ trans.info().log("Starting Connection Process");
+
+ noAvg = env.newTransNoAvg();
+ noAvg.setUser(new BatchPrincipal("batch:Expiring"));
+
+ TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
+ try {
+ crPrint = new CredPrint("Expired:");
+
+ TimeTaken tt = trans.start("Connect to Cluster with DAOs", Env.REMOTE);
+ try {
+ urFutureApprove = new URFutureApprove(trans, cluster,isDryRun());
+ checkOrganizationAcccess(trans, urFutureApprove.question());
+ urFutureApproveExec = new URFutureApproveExec(trans, urFutureApprove);
+ urPrint = new URPrint("User Roles:");
+ crDelete = new CredDelete(trans, urFutureApprove);
+ urDelete = new URDelete(trans,urFutureApprove);
+ cacheTouch = new CacheTouch(trans, urFutureApprove);
+
+ // Reusing... don't destroy
+ apprDAO = urFutureApprove.question().approvalDAO;
+ futureDAO = urFutureApprove.question().futureDAO;
+
+ TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = urFutureApprove.getSession(trans);
+ } finally {
+ tt2.done();
+ }
+ } finally {
+ tt.done();
+ }
+
+ File data_dir = new File(env.getProperty("aaf_data_dir"));
+ if(!data_dir.exists() || !data_dir.canWrite() || !data_dir.canRead()) {
+ throw new IOException("Cannot read/write to Data Directory "+ data_dir.getCanonicalPath() + ": EXITING!!!");
+ }
+ UserRole.setDeleteStream(
+ urDeleteF = new PrintStream(new FileOutputStream(deletesFile = new File(data_dir,"UserRoleDeletes.dat"),false)));
+ UserRole.setRecoverStream(
+ urRecoverF = new PrintStream(new FileOutputStream(new File(data_dir,"UserRoleRecover.dat"),false)));
+ UserRole.load(trans, session, UserRole.v2_0_11);
+
+ Cred.load(trans, session);
+ NS.load(trans, session,NS.v2_0_11);
+ Future.load(trans,session,Future.withConstruct);
+ Approval.load(trans,session,Approval.v2_0_17);
+ Role.load(trans, session);
+
+ email = new Email();
+ email.subject("AAF Expiring Process Alert (ENV: %s)",batchEnv);
+ email.preamble("Expiring Process Alert for %s",batchEnv);
+ email.signature("Sincerely,\nAAF Expiring Batch Process\n");
+ String address = env.getProperty("ALERT_TO_ADDRESS");
+ if(address==null) {
+ throw new APIException("ALERT_TO_ADDRESS property is required");
+ }
+ email.addTo(address);
+
+ } catch (OrganizationException e) {
+ throw new APIException("Error getting valid Organization",e);
+ } finally {
+ tt0.done();
+ }
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ // Setup Date boundaries
+
+ final GregorianCalendar gc = new GregorianCalendar();
+ final Date now = gc.getTime();
+
+ gc.add(GregorianCalendar.MONTH, 1);
+ Date future = gc.getTime();
+// Date earliest = null;
+
+ // reset
+ gc.setTime(now);
+ gc.add(GregorianCalendar.DAY_OF_MONTH, -7); // save Expired Roles for 7 days.
+ Date tooLate = gc.getTime();
+
+ TimeTaken tt;
+
+ // Clean out Approvals UserRoles are fixed up.
+ String memo;
+ for(List<Approval> la : Approval.byUser.values()) {
+ for(Approval a : la ) {
+ memo = a.getMemo();
+ if(memo!=null && (memo.contains("Re-Approval") || memo.contains("Re-Validate"))) {
+ String role = a.getRole();
+ if(role!=null) {
+ UserRole ur = UserRole.get(a.getUser(), a.getRole());
+ Future f=null;
+ if(ur!=null) {
+ if(ur.expires().after(future)) { // no need for Approval anymore
+ a.delayDelete(noAvg, apprDAO, dryRun, "User Role already Extended");
+ UUID tkt = a.getTicket();
+ if(tkt!=null) {
+ f = Future.data.get(tkt);
+ }
+ }
+ } else {
+ a.delayDelete(noAvg, apprDAO, dryRun, "User Role does not exist");
+ f = Future.data.get(a.getTicket());
+ }
+ if(f!=null) {
+ f.delayedDelete(noAvg, futureDAO, dryRun, "Approvals removed");
+ }
+ }
+ }
+ }
+ }
+ try {
+ trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
+ Future.resetLocalData();
+ Approval.resetLocalData();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ // Run for Expired Futures
+ trans.info().log("Checking for Expired Approval/Futures");
+ tt = trans.start("Delete old Futures", Env.REMOTE);
+ trans.info().log("### Running Future Execution on ",Future.data.size(), "Items");
+ // Execute any Futures waiting
+ for(Future f : Future.data.values()) {
+ if(f.memo().contains("Re-Approval") || f.memo().contains("Re-Validate")) {
+ List<Approval> la = Approval.byTicket.get(f.id());
+ if(la!=null) {
+ Result<OP_STATUS> ruf = urFutureApproveExec.exec(noAvg,la,f);
+ if(ruf.isOK()) {
+ switch(ruf.value) {
+ case P:
+ break;
+ case E:
+ case D:
+ case L:
+ f.delayedDelete(noAvg, futureDAO, dryRun,OP_STATUS.L.desc());
+ Approval.delayDelete(noAvg, apprDAO, dryRun, la,OP_STATUS.L.desc());
+ break;
+ }
+ }
+ }
+ }
+ }
+ try {
+ trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
+ Future.resetLocalData();
+ Approval.resetLocalData();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+
+ trans.info().log("### Remove Expired on ",Future.data.size(), "Items, or premature ones");
+ // Remove Expired
+ String expiredBeforeNow = "Expired before " + tooLate;
+ String expiredAfterFuture = "Expired after " + future;
+ try {
+ for(Future f : Future.data.values()) {
+ if(f.expires().before(tooLate)) {
+ f.delayedDelete(noAvg,futureDAO,dryRun, expiredBeforeNow);
+ Approval.delayDelete(noAvg, apprDAO, dryRun, Approval.byTicket.get(f.id()), expiredBeforeNow);
+ } else if(f.expires().after(future)) {
+ f.delayedDelete(noAvg,futureDAO,dryRun, expiredAfterFuture);
+ Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), expiredAfterFuture);
+ }
+ }
+ try {
+ trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
+ Future.resetLocalData();
+ Approval.resetLocalData();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ } finally {
+ tt.done();
+ }
+
+ trans.info().log("### Checking Approvals valid (",Approval.byApprover.size(),"Items)");
+ // Make sure users of Approvals are still valid
+ for(List<Approval> lapp : Approval.byTicket.values()) {
+ for(Approval app : lapp) {
+ Future f;
+ if(app.getTicket()==null) {
+ f = null;
+ } else {
+ f = Future.data.get(app.getTicket());
+ if(Future.pendingDelete(f)) {
+ f=null;
+ }
+ }
+ String msg;
+ if(f!=null && app.getRole()!=null && Role.byName.get(app.getRole())==null) {
+ f.delayedDelete(noAvg,futureDAO,dryRun,msg="Role '" + app.getRole() + "' no longer exists");
+ Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
+ continue;
+ }
+
+ switch(app.getStatus()) {
+ case "pending":
+ if(f==null) {
+ app.delayDelete(noAvg,apprDAO, isDryRun(), "ticketDeleted");
+ continue;
+ }
+ switch(app.getType()) {
+ case "owner":
+ boolean anOwner=false;
+ String approle = app.getRole();
+ if(approle!=null) {
+ Role role = Role.byName.get(approle);
+ if(role==null) {
+ app.delayDelete(noAvg, apprDAO, dryRun, "Role No Longer Exists");
+ continue;
+ } else {
+ // Make sure Owner Role exists
+ String owner = role.ns + ".owner";
+ if(Role.byName.containsKey(owner)) {
+ List<UserRole> lur = UserRole.byRole.get(owner);
+ if(lur != null) {
+ for(UserRole ur : lur) {
+ if(ur.user().equals(app.getApprover())) {
+ anOwner = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(!anOwner) {
+ app.delayDelete(noAvg, apprDAO, dryRun, "No longer Owner");
+ }
+
+ }
+ break;
+ case "supervisor":
+ try {
+ Identity identity = org.getIdentity(noAvg, app.getUser());
+ if(identity==null) {
+ if(f!=null) {
+ f.delayedDelete(noAvg,futureDAO,dryRun,msg = app.getUser() + " is no longer associated with " + org.getName());
+ Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
+ }
+ } else {
+ if(!app.getApprover().equals(identity.responsibleTo().fullID())) {
+ if(f!=null) {
+ f.delayedDelete(noAvg,futureDAO,dryRun,msg = app.getApprover() + " is no longer a Supervisor of " + app.getUser());
+ Approval.delayDelete(noAvg,apprDAO,dryRun, Approval.byTicket.get(f.id()), msg);
+ }
+ }
+ }
+ } catch (OrganizationException e) {
+ e.printStackTrace();
+ }
+ break;
+ }
+ break;
+ }
+ }
+ }
+ try {
+ trans.info().log("### Removed",Future.sizeForDeletion(),"Future and",Approval.sizeForDeletion(),"Approvals");
+ Future.resetLocalData();
+ Approval.resetLocalData();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ int count = 0, deleted=0, delayedURDeletes = 0;
+
+ // Run for User Roles
+ trans.info().log("Checking for Expired User Roles");
+ try {
+ for(UserRole ur : UserRole.data) {
+ if(org.getIdentity(noAvg, ur.user())==null) { // if not part of Organization;
+ if(isSpecial(ur.user())) {
+ trans.info().log(ur.user(),"is not part of organization, but may not be deleted");
+ } else {
+ ur.delayDelete(noAvg, "Not Part of Organization", dryRun);
+ ++deleted;
+ ++delayedURDeletes;
+ }
+ } else {
+ if(NS.data.get(ur.ns())==null) {
+ ur.delayDelete(noAvg,"Namespace " + ur.ns() + " does not exist.",dryRun);
+ ++delayedURDeletes;
+ ++deleted;
+ } else if(!Role.byName.containsKey(ur.role())) {
+ ur.delayDelete(noAvg,"Role " + ur.role() + " does not exist.",dryRun);
+ ++deleted;
+ ++delayedURDeletes;
+ } else if(ur.expires().before(tooLate)) {
+ if("owner".equals(ur.rname())) { // don't delete Owners, even if Expired
+ urPrint.exec(noAvg,ur,"Owner Expired (but not deleted)");
+ } else {
+ // In this case, when UR is expired, not dependent on other lookups, we delete straight out.
+ urDelete.exec(noAvg, ur,"Expired before " + tooLate);
+ ++deleted;
+ }
+ //trans.logAuditTrail(trans.info());
+ } else if(ur.expires().before(future) && ur.expires().after(now)) {
+ ++count;
+ // Is there an Approval set already
+ boolean needNew = true;
+ if(ur.role()!=null && ur.user()!=null) {
+ List<Approval> abm = Approval.byUser.get(ur.user());
+ if(abm!=null) {
+ for(Approval a : abm) {
+ if(a.getOperation().equals(FUTURE_OP.A.name()) && ur.role().equals(a.getRole())) {
+ if(Future.data.get(a.getTicket())!=null) {
+ needNew = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if(needNew) {
+ urFutureApprove.exec(noAvg, ur,"");
+ }
+ }
+ }
+ }
+ } catch (OrganizationException e) {
+ env.info().log(e,"Exiting ...");
+ } finally {
+ env.info().log("Found",count,"user roles expiring before",future);
+ env.info().log("deleting",deleted,"user roles expiring before",tooLate);
+ }
+
+ // Actualize UR Deletes, or send Email
+ if(UserRole.sizeForDeletion()>0) {
+ count+=UserRole.sizeForDeletion();
+ double onePercent = 0.01;
+ if(((double)UserRole.sizeForDeletion())/UserRole.data.size() > onePercent) {
+ Message msg = new Message();
+ try {
+ msg.line("Found %d of %d UserRoles marked for Deletion in file %s",
+ delayedURDeletes,UserRole.data.size(),deletesFile.getCanonicalPath());
+ } catch (IOException e) {
+ msg.line("Found %d of %d UserRoles marked for Deletion.\n",
+ delayedURDeletes);
+ }
+ msg.line("Review the File. If data is ok, Use ExpiringP2 BatchProcess to complete the deletions");
+
+ email.msg(msg);
+ email.exec(trans, org, "Email Support");
+ } else {
+ urDeleteF.flush();
+ try {
+ BufferedReader br = new BufferedReader(new FileReader(deletesFile));
+ try {
+ ExpiringP2.deleteURs(noAvg, br, urDelete, null /* don't touch Cache here*/);
+ } finally {
+ br.close();
+ }
+ } catch (IOException io) {
+ noAvg.error().log(io);
+ }
+ }
+ }
+ if(count>0) {
+ String str = String.format("%d UserRoles modified or deleted", count);
+ cacheTouch.exec(trans, "user_role", str);
+ }
+
+ // Run for Creds
+ trans.info().log("Checking for Expired Credentials");
+ System.out.flush();
+ count = 0;
+ try {
+ CredDAO.Data crd = new CredDAO.Data();
+ Date last = null;
+ for( Cred creds : Cred.data.values()) {
+ crd.id = creds.id;
+ for(int type : creds.types()) {
+ crd.type = type;
+ for( Instance inst : creds.instances) {
+ if(inst.expires.before(tooLate)) {
+ crd.expires = inst.expires;
+ crDelete.exec(noAvg, crd,"Expired before " + tooLate);
+ } else if(last==null || inst.expires.after(last)) {
+ last = inst.expires;
+ }
+ }
+ if(last!=null) {
+ if(last.before(future)) {
+ crd.expires = last;
+ crPrint.exec(noAvg, crd,"");
+ ++count;
+ }
+ }
+ }
+ }
+ } finally {
+ String str = String.format("Found %d current creds expiring before %s", count, Chrono.dateOnlyStamp(future));
+ if(count>0) {
+ cacheTouch.exec(trans, "cred", str);
+ }
+ }
+
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ for(Action<?,?,?> action : new Action<?,?,?>[] {crDelete}) {
+ if(action instanceof ActionDAO) {
+ ((ActionDAO<?,?,?>)action).close(trans);
+ }
+ }
+ session.close();
+ urDeleteF.close();
+ urRecoverF.close();
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/ExpiringP2.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/ExpiringP2.java
new file mode 100644
index 00000000..f568b330
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/ExpiringP2.java
@@ -0,0 +1,158 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.update;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.aaf.auth.Batch;
+import org.onap.aaf.auth.BatchPrincipal;
+import org.onap.aaf.auth.actions.Action;
+import org.onap.aaf.auth.actions.ActionDAO;
+import org.onap.aaf.auth.actions.CacheTouch;
+import org.onap.aaf.auth.actions.URDelete;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.cadi.util.Split;
+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.util.Chrono;
+
+public class ExpiringP2 extends Batch {
+ private final URDelete urDelete;
+ private final CacheTouch cacheTouch;
+ private final AuthzTrans noAvg;
+ private final BufferedReader urDeleteF;
+
+ public ExpiringP2(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+ trans.info().log("Starting Connection Process");
+
+ noAvg = env.newTransNoAvg();
+ noAvg.setUser(new BatchPrincipal("batch:ExpiringP2"));
+
+ TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
+ try {
+ urDelete = new URDelete(trans, cluster,isDryRun());
+ TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = urDelete.getSession(trans);
+ } finally {
+ tt2.done();
+ }
+ cacheTouch = new CacheTouch(trans,urDelete);
+
+ File data_dir = new File(env.getProperty("aaf_data_dir"));
+ if(!data_dir.exists() || !data_dir.canWrite() || !data_dir.canRead()) {
+ throw new IOException("Cannot read/write to Data Directory "+ data_dir.getCanonicalPath() + ": EXITING!!!");
+ }
+ urDeleteF = new BufferedReader(new FileReader(new File(data_dir,"UserRoleDeletes.dat")));
+
+ } finally {
+ tt0.done();
+ }
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ deleteURs(noAvg, urDeleteF, urDelete, cacheTouch);
+ }
+
+ public static void deleteURs(AuthzTrans trans, BufferedReader urDeleteF, URDelete urDelete, CacheTouch cacheTouch) {
+ String line,prev="";
+ try {
+ UserRole ur;
+ Map<String,Count> tally = new HashMap<String,Count>();
+ int count=0;
+ try {
+ while((line=urDeleteF.readLine())!=null) {
+ if(line.startsWith("#")) {
+ Count cnt = tally.get(line);
+ if(cnt==null) {
+ tally.put(line, cnt=new Count());
+ }
+ cnt.inc();
+ prev = line;
+ } else {
+ String[] l = Split.splitTrim('|', line);
+ try {
+ // Note: following default order from "COPY TO"
+ ur = new UserRole(l[0],l[1],l[3],l[4],Chrono.iso8601Fmt.parse(l[2]));
+ urDelete.exec(trans, ur, prev);
+ ++count;
+ } catch (ParseException e) {
+ trans.error().log(e);
+ }
+ }
+ }
+
+ System.out.println("Tallies of UserRole Deletions");
+ for(Entry<String, Count> es : tally.entrySet()) {
+ System.out.printf(" %6d\t%20s\n", es.getValue().cnt,es.getKey());
+ }
+ } finally {
+ if(cacheTouch!=null && count>0) {
+ cacheTouch.exec(trans, "user_roles", "Removing UserRoles");
+ }
+ }
+ } catch (IOException e) {
+ trans.error().log(e);
+ }
+
+ }
+ private static class Count {
+ private int cnt=0;
+
+ public /*synchonized*/ void inc() {
+ ++cnt;
+ }
+
+ public String toString() {
+ return Integer.toString(cnt);
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ for(Action<?,?,?> action : new Action<?,?,?>[] {urDelete,cacheTouch}) {
+ if(action instanceof ActionDAO) {
+ ((ActionDAO<?,?,?>)action).close(trans);
+ }
+ }
+ session.close();
+ try {
+ urDeleteF.close();
+ } catch (IOException e) {
+ trans.error().log(e);
+ }
+ }
+
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyApprovals.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyApprovals.java
new file mode 100644
index 00000000..3314694e
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyApprovals.java
@@ -0,0 +1,236 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.update;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.onap.aaf.auth.Batch;
+import org.onap.aaf.auth.BatchPrincipal;
+import org.onap.aaf.auth.actions.Email;
+import org.onap.aaf.auth.actions.EmailPrint;
+import org.onap.aaf.auth.actions.Message;
+import org.onap.aaf.auth.dao.CassAccess;
+import org.onap.aaf.auth.dao.cass.ApprovalDAO;
+import org.onap.aaf.auth.dao.cass.FutureDAO;
+import org.onap.aaf.auth.dao.cass.HistoryDAO;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Approval;
+import org.onap.aaf.auth.helpers.Future;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.auth.org.Organization.Identity;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.util.Chrono;
+
+public class NotifyApprovals extends Batch {
+ private static final String LINE = "----------------------------------------------------------------";
+ private final HistoryDAO historyDAO;
+ private final ApprovalDAO apprDAO;
+ private final FutureDAO futureDAO;
+ private Email email;
+ private int maxEmails;
+ private final PrintStream ps;
+ private final AuthzTrans noAvg;
+
+ public NotifyApprovals(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+
+ noAvg = env.newTransNoAvg();
+ noAvg.setUser(new BatchPrincipal("batch:NotifyApprovals"));
+
+ historyDAO = new HistoryDAO(trans, cluster, CassAccess.KEYSPACE);
+ session = historyDAO.getSession(trans);
+ apprDAO = new ApprovalDAO(trans, historyDAO);
+ futureDAO = new FutureDAO(trans, historyDAO);
+ if(isDryRun()) {
+ email = new EmailPrint();
+ maxEmails=3;
+ } else {
+ email = new Email();
+ maxEmails = Integer.parseInt(trans.getProperty("MAX_EMAILS","3"));
+ }
+ email.subject("AAF Approval Notification (ENV: %s)",batchEnv);
+ email.preamble("AAF (MOTS 22830) is the AT&T Authorization System used by many AT&T Tools and Applications." +
+ "\n Your approval is required, which you may enter on the following page:"
+ + "\n\n\t%s/approve\n\n"
+ ,env.getProperty(GUI_URL));
+ email.signature("Sincerely,\nAAF Team (Our MOTS# 22830)\n"
+ + "https://wiki.web.att.com/display/aaf/Contact+Us\n"
+ + "(Use 'Other Misc Requests (TOPS)')");
+
+ Approval.load(trans, session, Approval.v2_0_17);
+ Future.load(trans, session, Future.v2_0_17); // Skip the Construct Data
+
+ ps = new PrintStream(new FileOutputStream(logDir() + "/email"+Chrono.dateOnlyStamp()+".log",true));
+ ps.printf("### Approval Notify %s for %s%s\n",Chrono.dateTime(),batchEnv,dryRun?", DryRun":"");
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ GregorianCalendar gc = new GregorianCalendar();
+ Date now = gc.getTime();
+ String today = Chrono.dateOnlyStamp(now);
+ gc.add(GregorianCalendar.MONTH, -1);
+ gc=null;
+
+
+ Message msg = new Message();
+ int emailCount = 0;
+ List<Approval> pending = new ArrayList<Approval>();
+ boolean isOwner,isSupervisor;
+ for(Entry<String, List<Approval>> es : Approval.byApprover.entrySet()) {
+ isOwner = isSupervisor = false;
+ String approver = es.getKey();
+ if(approver.indexOf('@')<0) {
+ approver += org.getRealm();
+ }
+ Date latestNotify=null, soonestExpire=null;
+ GregorianCalendar latest=new GregorianCalendar();
+ GregorianCalendar soonest=new GregorianCalendar();
+ pending.clear();
+
+ for(Approval app : es.getValue()) {
+ Future f = app.getTicket()==null?null:Future.data.get(app.getTicket());
+ if(f==null) { // only Ticketed Approvals are valid.. the others are records.
+ // Approvals without Tickets are no longer valid.
+ if("pending".equals(app.getStatus())) {
+ app.setStatus("lapsed");
+ app.update(noAvg,apprDAO,dryRun); // obeys dryRun
+ }
+ } else {
+ if((soonestExpire==null && f.expires()!=null) || (soonestExpire!=null && f.expires()!=null && soonestExpire.before(f.expires()))) {
+ soonestExpire=f.expires();
+ }
+
+ if("pending".equals(app.getStatus())) {
+ if(!isOwner) {
+ isOwner = "owner".equals(app.getType());
+ }
+ if(!isSupervisor) {
+ isSupervisor = "supervisor".equals(app.getType());
+ }
+
+ if((latestNotify==null && app.getLast_notified()!=null) ||(latestNotify!=null && app.getLast_notified()!=null && latestNotify.before(app.getLast_notified()))) {
+ latestNotify=app.getLast_notified();
+ }
+ pending.add(app);
+ }
+ }
+ }
+
+ if(!pending.isEmpty()) {
+ boolean go = false;
+ if(latestNotify==null) { // never notified... make it so
+ go=true;
+ } else {
+ if(!today.equals(Chrono.dateOnlyStamp(latest))) { // already notified today
+ latest.setTime(latestNotify);
+ soonest.setTime(soonestExpire);
+ int year;
+ int days = soonest.get(GregorianCalendar.DAY_OF_YEAR)-latest.get(GregorianCalendar.DAY_OF_YEAR);
+ days+=((year=soonest.get(GregorianCalendar.YEAR))-latest.get(GregorianCalendar.YEAR))*365 +
+ (soonest.isLeapYear(year)?1:0);
+ if(days<7) { // If Expirations get within a Week (or expired), notify everytime.
+ go = true;
+ }
+ }
+ }
+ if(go) {
+ if(maxEmails>emailCount++) {
+ try {
+ Organization org = OrganizationFactory.obtain(env, approver);
+ Identity user = org.getIdentity(noAvg, approver);
+ if(user==null) {
+ ps.printf("Invalid Identity: %s\n", approver);
+ } else {
+ email.clear();
+ msg.clear();
+ email.addTo(user.email());
+ msg.line(LINE);
+ msg.line("Why are you receiving this Notification?\n");
+ if(isSupervisor) {
+ msg.line("%sYou are the supervisor of one or more employees who need access to tools which are protected by AAF. " +
+ "Your employees may ask for access to various tools and applications to do their jobs. ASPR requires "
+ + "that you are notified and approve their requests. The details of each need is provided when you click "
+ + "on webpage above.\n",isOwner?"1) ":"");
+ msg.line("Your participation in this process fulfills the ASPR requirement to re-authorize users in roles on a regular basis.\n\n");
+ }
+
+ if(isOwner) {
+ msg.line("%sYou are the listed owner of one or more AAF Namespaces. ASPR requires that those responsible for "
+ + "applications and their access review them regularly for accuracy. The AAF WIKI page for AT&T is https://wiki.web.att.com/display/aaf. "
+ + "More info regarding questions of being a Namespace Owner is available at https://wiki.web.att.com/pages/viewpage.action?pageId=594741363\n",isSupervisor?"2) ":"");
+ msg.line("Additionally, Credentials attached to the Namespace must be renewed regularly. While you may delegate certain functions to " +
+ "Administrators within your Namespace, you are ultimately responsible to make sure credentials do not expire.\n");
+ msg.line("You may view the Namespaces you listed as Owner for in this AAF Env by viewing the following webpage:\n");
+ msg.line(" %s/ns\n\n",env.getProperty(GUI_URL));
+
+ }
+ msg.line(" If you are unfamiliar with AAF, you might like to peruse the following links:"
+ + "\n\thttps://wiki.web.att.com/display/aaf/AAF+in+a+Nutshell"
+ + "\n\thttps://wiki.web.att.com/display/aaf/The+New+Person%%27s+Guide+to+AAF");
+ msg.line("\n SPECIAL NOTE about SWM Management Groups: Understand that SWM management Groups correlate one-to-one to AAF Namespaces. "
+ + "(SWM uses AAF for the Authorization piece of Management Groups). You may be assigned the SWM Management Group by asking "
+ + "directly, or through any of the above stated automated processes. Auto-generated Namespaces typically look like 'com.att.44444.PROD' "
+ + "where '44444' is a MOTS ID, and 'PROD' is PROD|DEV|TEST, etc. For your convenience, the MOTS link is http://ebiz.sbc.com/mots.\n");
+ msg.line(" Finally, realize that there are automated processes which create Machines and Resources via SWM, Kubernetes or other "
+ + "such tooling. If you or your predecessor requested them, you were set as the owner of the AAF Namespace created during "
+ + "that process.\n");
+ msg.line(" For ALL QUESTIONS of why and how of SWM, and whether you or your reports can be removed, please contact SWM at "
+ + "https://wiki.web.att.com/display/swm/Support\n");
+
+ email.msg(msg);
+ email.exec(noAvg, org,"");
+ if(!isDryRun()) {
+ email.log(ps,"NotifyApprovals");
+ for(Approval app : pending) {
+ app.setLastNotified(now);
+ app.update(noAvg, apprDAO, dryRun);
+ }
+ }
+ }
+ } catch (OrganizationException e) {
+ trans.info().log(e);
+ }
+ }
+ }
+ }
+ }
+ trans.info().printf("%d emails sent for %s", emailCount,batchEnv);
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ futureDAO.close(trans);
+ apprDAO.close(trans);
+ historyDAO.close(trans);
+ ps.close();
+ }
+}
diff --git a/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java
new file mode 100644
index 00000000..bdf8347c
--- /dev/null
+++ b/auth/auth-batch/src/main/java/org/onap/aaf/auth/update/NotifyCredExpiring.java
@@ -0,0 +1,321 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.update;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.onap.aaf.auth.Batch;
+import org.onap.aaf.auth.BatchPrincipal;
+import org.onap.aaf.auth.actions.Email;
+import org.onap.aaf.auth.actions.EmailPrint;
+import org.onap.aaf.auth.actions.Message;
+import org.onap.aaf.auth.dao.cass.CredDAO;
+import org.onap.aaf.auth.dao.hl.Question;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.helpers.Cred;
+import org.onap.aaf.auth.helpers.Notification;
+import org.onap.aaf.auth.helpers.UserRole;
+import org.onap.aaf.auth.helpers.Notification.TYPE;
+import org.onap.aaf.auth.layer.Result;
+import org.onap.aaf.auth.org.EmailWarnings;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.auth.org.Organization.Identity;
+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.util.Chrono;
+
+import java.util.TreeMap;
+
+
+public class NotifyCredExpiring extends Batch {
+
+ private static final String UNKNOWN_ID = "unknown@deprecated.id";
+ private static final String AAF_INSTANTIATED_MECHID = "AAF INSTANTIATED MECHID";
+ private static final String EXPIRATION_DATE = "EXPIRATION DATE";
+ private static final String QUICK_LINK = "QUICK LINK TO UPDATE PAGE";
+ private static final String DASH_1 = "-----------------------";
+ private static final String DASH_2 = "---------------";
+ private static final String DASH_3 = "----------------------------------------------------";
+ private static final String LINE = "\n----------------------------------------------------------------";
+ private Email email;
+ private int maxEmails;
+ private final PrintStream ps;
+ private final AuthzTrans noAvg;
+ private String supportEmailAddr;
+
+ public NotifyCredExpiring(AuthzTrans trans) throws APIException, IOException, OrganizationException {
+ super(trans.env());
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+
+ noAvg = env.newTransNoAvg();
+ noAvg.setUser(new BatchPrincipal("batch:NotifyCredExpiring"));
+
+ if((supportEmailAddr = env.getProperty("mailFromUserId"))==null) {
+ throw new APIException("mailFromUserId property must be set");
+ }
+ if(isDryRun()) {
+ email = new EmailPrint();
+ maxEmails=3;
+ maxEmails = Integer.parseInt(trans.getProperty("MAX_EMAILS","3"));
+ } else {
+ email = new Email();
+ maxEmails = Integer.parseInt(trans.getProperty("MAX_EMAILS","3"));
+ }
+
+ email.subject("AAF Password Expiration Notification (ENV: %s)",batchEnv);
+ email.preamble("AAF (MOTS 22830) is the AT&T Authorization System used by many AT&T Tools and Applications.\n\n" +
+ " The following Credentials are expiring on the dates shown. Failure to act before the expiration date "
+ + "will cause your App's Authentications to fail.\n");
+ email.signature("Sincerely,\nAAF Team (Our MOTS# 22830)\n"
+ + "https://wiki.web.att.com/display/aaf/Contact+Us\n"
+ + "(Use 'Other Misc Requests (TOPS)')");
+
+ Cred.load(trans, session,CredDAO.BASIC_AUTH, CredDAO.BASIC_AUTH_SHA256);
+ Notification.load(trans, session, Notification.v2_0_18);
+ UserRole.load(trans, session, UserRole.v2_0_11);
+
+ ps = new PrintStream(new FileOutputStream(logDir() + "/email"+Chrono.dateOnlyStamp()+".log",true));
+ ps.printf("### Approval Notify %s for %s%s\n",Chrono.dateTime(),batchEnv,dryRun?", DryRun":"");
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+
+ EmailWarnings ewp = org.emailWarningPolicy();
+ long now = System.currentTimeMillis();
+ Date early = new Date(now+(ewp.credExpirationWarning()*2)); // 2 months back
+ Date must = new Date(now+ewp.credExpirationWarning()); // 1 months back
+ Date critical = new Date(now+ewp.emailUrgentWarning()); // 1 week
+ Date within2Weeks = new Date(now+604800000 * 2);
+ Date withinLastWeek = new Date(now-604800000);
+ Date tooLate = new Date(now);
+
+ // Temp structures
+ Map<String,Cred> lastCred = new HashMap<String,Cred>();
+ Map<String,List<LastCred>> ownerCreds = new TreeMap<String,List<LastCred>>();
+ Date last;
+
+
+ List<LastCred> noOwner = new ArrayList<LastCred>();
+ ownerCreds.put(UNKNOWN_ID,noOwner);
+
+ // Get a list of ONLY the ones needing email by Owner
+ for(Entry<String, List<Cred>> es : Cred.byNS.entrySet()) {
+ lastCred.clear();
+ for(Cred c : es.getValue()) {
+ last = c.last(CredDAO.BASIC_AUTH,CredDAO.BASIC_AUTH_SHA256);
+ if(last!=null && last.after(tooLate) && last.before(early)) {
+ List<UserRole> ownerURList = UserRole.byRole.get(es.getKey()+".owner");
+ if(ownerURList!=null) {
+ for(UserRole ur:ownerURList) {
+ String owner = ur.user();
+ List<LastCred> llc = ownerCreds.get(owner);
+ if(llc==null) {
+ ownerCreds.put(owner, (llc=new ArrayList<LastCred>()));
+ }
+ llc.add(new LastCred(c,last));
+ }
+ } else {
+ noOwner.add(new LastCred(c,last));
+ }
+ }
+ }
+ }
+
+ boolean bCritical,bNormal,bEarly;
+ int emailCount=0;
+ Message msg = new Message();
+ Notification ownNotf;
+ StringBuilder logMessage = new StringBuilder();
+ for(Entry<String,List<LastCred>> es : ownerCreds.entrySet()) {
+ String owner = es.getKey();
+ boolean header = true;
+ try {
+ Organization org = OrganizationFactory.obtain(env, owner);
+ Identity user = org.getIdentity(noAvg, owner);
+ if(!UNKNOWN_ID.equals(owner) && user==null) {
+ ps.printf("Invalid Identity: %s\n", owner);
+ } else {
+ logMessage.setLength(0);
+ if(maxEmails>emailCount) {
+ bCritical=bNormal=bEarly = false;
+ email.clear();
+ msg.clear();
+ email.addTo(user==null?supportEmailAddr:user.email());
+
+ ownNotf = Notification.get(es.getKey(),TYPE.CN);
+ if(ownNotf==null) {
+ ownNotf = Notification.create(user==null?UNKNOWN_ID:user.fullID(), TYPE.CN);
+ }
+ last = ownNotf.last;
+ // Get Max ID size for formatting purposes
+ int length = AAF_INSTANTIATED_MECHID.length();
+ for(LastCred lc : es.getValue()) {
+ length = Math.max(length, lc.cred.id.length());
+ }
+ String id_exp_fmt = "\t%-"+length+"s %15s %s";
+
+ Collections.sort(es.getValue(),LastCred.COMPARE);
+ for(LastCred lc : es.getValue()) {
+ if(lc.last.after(must) && lc.last.before(early) &&
+ (ownNotf.last==null || ownNotf.last.before(withinLastWeek))) {
+ if(!bEarly && header) {
+ msg.line("\tThe following are friendly 2 month reminders, just in case you need to schedule your updates early. "
+ + "You will be reminded next month\n");
+ msg.line(id_exp_fmt, AAF_INSTANTIATED_MECHID,EXPIRATION_DATE, QUICK_LINK);
+ msg.line(id_exp_fmt, DASH_1, DASH_2, DASH_3);
+ header = false;
+ }
+ bEarly = true;
+ } else if(lc.last.after(critical) && lc.last.before(must) &&
+ (ownNotf.last==null || ownNotf.last.before(withinLastWeek))) {
+ if(!bNormal) {
+ boolean last2wks = lc.last.before(within2Weeks);
+ if(last2wks) {
+ try {
+ Identity supvsr = user.responsibleTo();
+ email.addCC(supvsr.email());
+ } catch(OrganizationException e) {
+ trans.error().log(e, "Supervisor cannot be looked up");
+ }
+ }
+ if(header) {
+ msg.line("\tIt is now important for you to update Passwords all all configurations using them for the following.\n" +
+ (last2wks?"\tNote: Your Supervisor is CCd\n":"\tNote: Your Supervisor will be notified if this is not being done before the last 2 weeks\n"));
+ msg.line(id_exp_fmt, AAF_INSTANTIATED_MECHID,EXPIRATION_DATE, QUICK_LINK);
+ msg.line(id_exp_fmt, DASH_1, DASH_2, DASH_3);
+ }
+ header = false;
+ }
+ bNormal=true;
+ } else if(lc.last.after(tooLate) && lc.last.before(critical)) { // Email Every Day, with Supervisor
+ if(!bCritical && header) {
+ msg.line("\t!!! WARNING: These Credentials will expire in LESS THAN ONE WEEK !!!!\n" +
+ "\tYour supervisor is added to this Email\n");
+ msg.line(id_exp_fmt, AAF_INSTANTIATED_MECHID,EXPIRATION_DATE, QUICK_LINK);
+ msg.line(id_exp_fmt, DASH_1, DASH_2, DASH_3);
+ header = false;
+ }
+ bCritical = true;
+ try {
+ if(user!=null) {
+ Identity supvsr = user.responsibleTo();
+ if(supvsr!=null) {
+ email.addCC(supvsr.email());
+ supvsr = supvsr.responsibleTo();
+ if(supvsr!=null) {
+ email.addCC(supvsr.email());
+ }
+ }
+ }
+ } catch(OrganizationException e) {
+ trans.error().log(e, "Supervisor cannot be looked up");
+ }
+ }
+ if(bEarly || bNormal || bCritical) {
+ if(logMessage.length()==0) {
+ logMessage.append("NotifyCredExpiring");
+ }
+ logMessage.append("\n\t");
+ logMessage.append(lc.cred.id);
+ logMessage.append('\t');
+ logMessage.append(Chrono.dateOnlyStamp(lc.last));
+ msg.line(id_exp_fmt, lc.cred.id, Chrono.dateOnlyStamp(lc.last)+" ",env.getProperty(GUI_URL)+"/creddetail?ns="+Question.domain2ns(lc.cred.id));
+ }
+ }
+
+ if(bEarly || bNormal || bCritical) {
+ msg.line(LINE);
+ msg.line("Why are you receiving this Notification?\n");
+ msg.line("You are the listed owner of one or more AAF Namespaces. ASPR requires that those responsible for "
+ + "applications and their access review them regularly for accuracy. The AAF WIKI page for AT&T is https://wiki.web.att.com/display/aaf. "
+ + "You might like https://wiki.web.att.com/display/aaf/AAF+in+a+Nutshell. More detailed info regarding questions of being a Namespace Owner is available at https://wiki.web.att.com/pages/viewpage.action?pageId=594741363\n");
+ msg.line("You may view the Namespaces you listed as Owner for in this AAF Env by viewing the following webpage:\n");
+ msg.line(" %s/ns\n\n",env.getProperty(GUI_URL));
+ email.msg(msg);
+ Result<Void> rv = email.exec(trans, org,"");
+ if(rv.isOK()) {
+ ++emailCount;
+ if(!isDryRun()) {
+ ownNotf.update(noAvg, session, false);
+ // SET LastNotification
+ }
+ email.log(ps,logMessage.toString());
+ } else {
+ trans.error().log(rv.errorString());
+ }
+ }
+ }
+ }
+ } catch (OrganizationException e) {
+ trans.info().log(e);
+ }
+ }
+ trans.info().printf("%d emails sent for %s", emailCount,batchEnv);
+ }
+
+ private static class LastCred {
+ public Cred cred;
+ public Date last;
+
+ public LastCred(Cred cred, Date last) {
+ this.cred = cred;
+ this.last = last;
+ }
+
+ // Reverse Sort (Oldest on top)
+ public static Comparator<LastCred> COMPARE = new Comparator<LastCred>() {
+ @Override
+ public int compare(LastCred o1, LastCred o2) {
+ return o2.last.compareTo(o1.last);
+ }
+ };
+
+ public String toString() {
+ return Chrono.dateTime(last) + cred.toString();
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ ps.close();
+ }
+}