Update project structure to org.onap.aaf
Update project structure of authz module in aaf from
com.att to org.onap.aaf and add distribution management
and repositories.
Issue-id: AAF-21
Change-Id: Ia2486954e99f2bd60f18122ed60d32d5590781e9
Signed-off-by: sg481n <sg481n@att.com>
diff --git a/authz-batch/pom.xml b/authz-batch/pom.xml
new file mode 100644
index 0000000..a2233f0
--- /dev/null
+++ b/authz-batch/pom.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>com.att.authz</groupId>
+ <artifactId>parent</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>authz-batch</artifactId>
+ <name>Authz Batch</name>
+ <description>Batch Processing for Authz</description>
+ <packaging>jar</packaging>
+ <url>https://github.com/att/AAF</url>
+ <licenses>
+ <license>
+ <name>BSD License</name>
+ <url> </url>
+ </license>
+ </licenses>
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email></email>
+ <organization>ATT</organization>
+ <organizationUrl></organizationUrl>
+ </developer>
+ </developers>
+
+ <properties>
+ <maven.test.failure.ignore>false</maven.test.failure.ignore>
+ <project.swmVersion>1</project.swmVersion>
+ </properties>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>org.onap.aaf.inno</groupId>
+ <artifactId>env</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.inno</groupId>
+ <artifactId>rosetta</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-aaf</artifactId>
+ </dependency>
+
+
+
+ <!-- <dependency>
+ <groupId>com.att.authz</groupId>
+ <artifactId>authz-att</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-aaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-client</artifactId>
+ </exclusion>
+ </exclusions>
+
+ </dependency> -->
+
+ <dependency>
+ <groupId>com.att.authz</groupId>
+ <artifactId>authz-cass</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-aaf</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>cadi-client</artifactId>
+ </exclusion>
+
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.joda</groupId>
+ <artifactId>joda-time</artifactId>
+ <version>2.5</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+
+ <!-- Data Migration
+ <dependency>
+ <groupId>com.oracle</groupId>
+ <artifactId>ojdbc6</artifactId>
+ <version>11.2.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.opencsv</groupId>
+ <artifactId>opencsv</artifactId>
+ <version>3.3</version>
+ </dependency>
+ -->
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.4</version>
+
+ <configuration>
+ <classifier>tests</classifier>
+ <archive>
+ <manifestEntries>
+ <Sealed>true</Sealed>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ <executions>
+ <execution>
+ <id>depends</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <descriptorRefs>
+ <descriptorRef>jar-with-dependencies</descriptorRef>
+ </descriptorRefs>
+ <archive>
+ <manifest>
+ <mainClass>com.att.authz.Batch</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </execution>
+ <execution>
+ <id>swm</id>
+ <phase>package</phase>
+ <goals>
+ <goal>single</goal>
+ </goals>
+ <configuration>
+ <finalName>authz-batch-${project.version}.${project.swmVersion}</finalName>
+ <descriptors>
+ <descriptor>../authz-service/src/main/assemble/swm.xml</descriptor>
+ </descriptors>
+ <archive>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <configuration>
+ <failOnError>false</failOnError>
+ </configuration>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-source-plugin</artifactId>
+ <version>2.2.1</version>
+ <executions>
+ <execution>
+ <id>attach-sources</id>
+ <goals>
+ <goal>jar-no-fork</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.5</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.sonatype.plugins</groupId>
+ <artifactId>nexus-staging-maven-plugin</artifactId>
+ <version>1.6.7</version>
+ <extensions>true</extensions>
+ <configuration>
+ <serverId>ossrhdme</serverId>
+ <nexusUrl>https://oss.sonatype.org/</nexusUrl>
+ <autoReleaseAfterClose>true</autoReleaseAfterClose>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/authz-batch/src/main/config/authBatch.props b/authz-batch/src/main/config/authBatch.props
new file mode 100644
index 0000000..cfe75e3
--- /dev/null
+++ b/authz-batch/src/main/config/authBatch.props
@@ -0,0 +1,36 @@
+##
+## AUTHZ Batch (authz-batch) Properties
+##
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+
+DRY_RUN=false
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.props;_COMMON_DIR_/com.att.aaf.common.props
+
+
+## -------------------------------------
+## Batch specific Settings
+## -------------------------------------
+SPECIAL_NAMES=testunused,testid,unknown
+
+
+## ----------------------------------------------
+## Email Server settings
+## ----------------------------------------------
+#Sender's email ID needs to be mentioned
+mailFromUserId=DL-aaf-support@att.com
+mailHost=smtp.it.att.com
+
+ALERT_TO_ADDRESS=DL-aaf-support@att.com
+
+PASSWORD_RESET_URL=_AUTHZ_GUI_URL_/gui/passwd
+APPROVALS_URL=_AUTHZ_GUI_URL_/gui/approve
+
+
diff --git a/authz-batch/src/main/config/log4j.properties b/authz-batch/src/main/config/log4j.properties
new file mode 100644
index 0000000..169460c
--- /dev/null
+++ b/authz-batch/src/main/config/log4j.properties
@@ -0,0 +1,84 @@
+###############################################################################
+# Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+###############################################################################
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+#
+log4j.rootLogger=INFO,FA
+log4j.logger.aspr=INFO,aspr
+log4j.additivity.aspr=false
+log4j.logger.authz-batch=INFO,authz-batch
+log4j.logger.sync=INFO,sync
+log4j.additivity.sync=false
+log4j.logger.jobchange=INFO,jobchange
+log4j.additivity.jobchange=false
+log4j.logger.validateuser=INFO,validateuser
+log4j.additivity.validateuser=false
+
+
+log4j.appender.FA=org.apache.log4j.RollingFileAppender
+log4j.appender.FA.File=${LOG4J_FILENAME_authz-batch}
+log4j.appender.FA.MaxFileSize=10000KB
+log4j.appender.FA.MaxBackupIndex=7
+log4j.appender.FA.layout=org.apache.log4j.PatternLayout
+log4j.appender.FA.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.stderr=org.apache.log4j.ConsoleAppender
+log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
+log4j.appender.stderr.layout.ConversionPattern=%d %p [%c] - %m %n
+log4j.appender.stderr.Target=System.err
+
+log4j.appender.authz-batch=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.authz-batch.encoding=UTF-8
+log4j.appender.authz-batch.layout=org.apache.log4j.PatternLayout
+log4j.appender.authz-batch.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.authz-batch.File=${LOG4J_FILENAME_authz-batch}
+log4j.appender.authz-batch.DatePattern='.'yyyy-MM
+
+log4j.appender.aspr=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.aspr.encoding=UTF-8
+log4j.appender.aspr.layout=org.apache.log4j.PatternLayout
+log4j.appender.aspr.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.aspr.File=${LOG4J_FILENAME_aspr}
+log4j.appender.aspr.DatePattern='.'yyyy-MM
+
+
+log4j.appender.jobchange=org.apache.log4j.RollingFileAppender
+log4j.appender.jobchange.File=${LOG4J_FILENAME_jobchange}
+log4j.appender.jobchange.MaxFileSize=10000KB
+log4j.appender.jobchange.MaxBackupIndex=7
+log4j.appender.jobchange.layout=org.apache.log4j.PatternLayout
+log4j.appender.jobchange.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.validateuser=org.apache.log4j.RollingFileAppender
+log4j.appender.validateuser.File=${LOG4J_FILENAME_validateuser}
+log4j.appender.validateuser.MaxFileSize=10000KB
+log4j.appender.validateuser.MaxBackupIndex=7
+log4j.appender.validateuser.layout=org.apache.log4j.PatternLayout
+log4j.appender.validateuser.layout.ConversionPattern=%d %p [%c] - %m %n
+
+log4j.appender.sync=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.sync.encoding=UTF-8
+log4j.appender.sync.layout=org.apache.log4j.PatternLayout
+log4j.appender.sync.layout.ConversionPattern=%d [%p] %m %n
+log4j.appender.sync.File=${LOG4J_FILENAME_sync}
+log4j.appender.sync.DatePattern='.'yyyy-MM
+
+# General Apache libraries
+log4j.logger.org.apache=WARN
+
diff --git a/authz-batch/src/main/java/com/att/authz/Batch.java b/authz-batch/src/main/java/com/att/authz/Batch.java
new file mode 100644
index 0000000..a31d55f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/Batch.java
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+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.Properties;
+import java.util.Set;
+import java.util.TimeZone;
+
+import org.apache.log4j.Logger;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.Organization;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import com.att.dao.CassAccess;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.StaticSlot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.impl.Log4JLogTarget;
+import org.onap.aaf.inno.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 StaticSlot ssargs;
+
+ protected static final String STARS = "*****";
+
+ protected final Cluster cluster;
+ protected static AuthzEnv env;
+ protected static Session session;
+ protected static Logger aspr;
+ private static Set<String> specialNames = null;
+ protected static boolean dryRun;
+ protected static String batchEnv;
+
+ public static final String CASS_ENV = "CASS_ENV";
+ protected final static String PUNT="punt";
+ 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 Batch(AuthzEnv env) throws APIException, IOException {
+ // TODO - Property Driven Organization
+// try {
+// // att = new ATT(env);
+// } catch (OrganizationException e) {
+// throw new APIException(e);
+// }
+
+ // 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,
+ // TEMP
+ ORA_URL, ORA_PASSWORD
+ }) {
+ 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.equals("false") ) {
+ dryRun = false;
+ } else {
+ dryRun = true;
+ env.info().log("dryRun set to TRUE");
+ }
+
+ // Special names to allow behaviors beyond normal rules
+ String names = env.getProperty( "SPECIAL_NAMES" );
+ if ( names != null )
+ {
+ env.info().log("Loading SPECIAL_NAMES");
+ specialNames = new HashSet<String>();
+ 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);
+ }
+ }
+
+ }
+
+ 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) {
+ Properties props = new Properties();
+ InputStream is=null;
+ String filename;
+ String propLoc;
+ try {
+ File f = new File("etc/authBatch.props");
+ try {
+ if(f.exists()) {
+ filename = f.getCanonicalPath();
+ is = new FileInputStream(f);
+ propLoc=f.getPath();
+ } else {
+ URL rsrc = ClassLoader.getSystemResource("authBatch.props");
+ filename = rsrc.toString();
+ is = rsrc.openStream();
+ propLoc=rsrc.getPath();
+ }
+ props.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(props);
+
+ 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("logs/").noPID();
+ } else {
+ lfn = new LogFileNamer("logs/" + batchEnv+'/').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 Property Driven Organization
+// 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
+ */
+
+ if( JobChange.class.getSimpleName().equals(toolName)) {
+ aspr.info( "Begin jobchange processing" );
+ batch = new JobChange(trans);
+ }
+ //// else if( ValidateUsers.class.getSimpleName().equals(toolName)) {
+ //// aspr.info( "Begin ValidateUsers processing" );
+ //// batch = new ValidateUsers(trans);
+ // }
+ else if( UserRoleDataGeneration.class.getSimpleName().equals(toolName)) {
+ // This job duplicates User Role add/delete History items
+ // so that we can search them by Role. Intended as a one-time
+ // script! but written as batch job because Java has better
+ // UUID support. Multiple runs will generate multiple copies of
+ // these history elements!
+ aspr.info( "Begin User Role Data Generation Processing ");
+ batch = new UserRoleDataGeneration(trans);
+ } else { // Might be a Report, Update or Temp Batch
+ Class<?> cls;
+ String classifier = "";
+ try {
+ cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.update."+toolName);
+ classifier = "Update:";
+ } catch(ClassNotFoundException e) {
+ try {
+ cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.reports."+toolName);
+ classifier = "Report:";
+ } catch (ClassNotFoundException e2) {
+ try {
+ cls = ClassLoader.getSystemClassLoader().loadClass("com.att.authz.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.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/authz-batch/src/main/java/com/att/authz/BatchException.java b/authz-batch/src/main/java/com/att/authz/BatchException.java
new file mode 100644
index 0000000..7247503
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/BatchException.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+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/authz-batch/src/main/java/com/att/authz/CassBatch.java b/authz-batch/src/main/java/com/att/authz/CassBatch.java
new file mode 100644
index 0000000..f251582
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/CassBatch.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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 {
+ 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/authz-batch/src/main/java/com/att/authz/FileCassBatch.java b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java
new file mode 100644
index 0000000..1044052
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/FileCassBatch.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.DirectoryIteratorException;
+import java.nio.file.DirectoryStream;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+
+public abstract class FileCassBatch extends CassBatch {
+
+ public FileCassBatch(AuthzTrans trans, String log4jName) throws APIException, IOException {
+ super(trans, log4jName);
+ }
+
+ protected List<File> findAllFiles(String regex) {
+ List<File> files = new ArrayList<File>();
+ FileSystem fileSystem = FileSystems.getDefault();
+ PathMatcher pathMatcher = fileSystem.getPathMatcher("glob:" + regex);
+ Path path = Paths.get(System.getProperty("user.dir"), "data");
+
+ try {
+ DirectoryStream<Path> directoryStream = Files.newDirectoryStream(
+ path, regex);
+ for (Path file : directoryStream) {
+ if (pathMatcher.matches(file.getFileName())) {
+ files.add(file.toFile());
+ }
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ } catch (DirectoryIteratorException ex) {
+ ex.printStackTrace();
+ }
+
+ return files;
+ }
+
+
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/JobChange.java b/authz-batch/src/main/java/com/att/authz/JobChange.java
new file mode 100644
index 0000000..e5672e6
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/JobChange.java
@@ -0,0 +1,743 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+// test for case where I'm an admin
+
+package com.att.authz;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.Organization;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class JobChange extends Batch
+{
+ private class UserRole
+ {
+ String user;
+ String role;
+ }
+ private class UserCred
+ {
+ String user;
+ String ns;
+ }
+
+ private class NamespaceOwner
+ {
+ String user;
+ String ns;
+ boolean responsible;
+ int ownerCount;
+ }
+
+
+ private AuthzTrans myTrans;
+
+ private Map<String, ArrayList<UserRole>> rolesMap = new HashMap<String, ArrayList<UserRole>>();
+ private Map<String, ArrayList<NamespaceOwner>> ownersMap = new HashMap<String, ArrayList<NamespaceOwner>>();
+ private Map<String, ArrayList<UserCred>> credsMap = new HashMap<String, ArrayList<UserCred>>();
+
+
+ public static void createDirectory( String dir )
+ {
+ File f = new File( dir );
+
+ if ( ! f.exists())
+ {
+ env.info().log( "creating directory: " + dir );
+ boolean result = false;
+
+ try
+ {
+ f.mkdir();
+ result = true;
+ } catch(SecurityException e){
+ e.printStackTrace();
+ }
+ if(result) {
+ System.out.println("DIR created");
+ }
+ }
+ }
+
+ public static String getJobChangeDataFile()
+ {
+ File outFile = null;
+ BufferedWriter writer = null;
+ BufferedReader reader = null;
+ String line;
+ boolean errorFlag = false;
+
+ try
+ {
+ createDirectory( "etc" );
+
+ outFile = new File("etc/jobchange." + getCurrentDate() );
+ if (!outFile.exists())
+ {
+ outFile.createNewFile();
+ }
+ else
+ {
+ return( "etc/jobchange." + getCurrentDate() );
+ }
+
+ env.info().log("Creating the local file with the webphone data");
+
+
+
+ writer = new BufferedWriter(new FileWriter(
+ outFile.getAbsoluteFile()));
+
+ URL u = new URL( "ftp://thprod37.sbc.com/jobchange_Delta.dat" );
+ reader = new BufferedReader(new InputStreamReader(
+ new BufferedInputStream(u.openStream())));
+ while ((line = reader.readLine()) != null) {
+ writer.write(line + "\n");
+ }
+
+ writer.close();
+ reader.close();
+
+ env.info().log("Finished fetching the data from the webphone ftp site.");
+ return( "etc/jobchange." + getCurrentDate() );
+
+ } catch (MalformedURLException e) {
+ env.error().log("Could not open the remote job change data file.", e);
+ errorFlag = true;
+
+ } catch (IOException e) {
+ env.error().log(
+ "Error while opening or writing to the local data file.", e);
+ errorFlag = true;
+
+ } catch (Exception e) {
+ env.error().log("Error while fetching the data file.", e);
+ errorFlag = true;
+
+ } finally {
+ if (errorFlag)
+ outFile.delete();
+ }
+ return null;
+ }
+
+ public static String getCurrentDate()
+ {
+ SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");
+ Date now = new Date();
+ String strDate = sdfDate.format(now);
+ return strDate;
+ }
+
+ public void loadUsersFromCred()
+ {
+ String query = "select id,ns from authz.cred" ;
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ ResultSet results = session.execute(stmt);
+
+ Iterator<Row> iter = results.iterator();
+ while( iter.hasNext() )
+ {
+ Row row = iter.next();
+ String user = row.getString( "id" );
+ String ns = row.getString( "ns" );
+ String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+ if ( isMechID( simpleUser ) )
+ {
+ continue;
+ }
+ else if ( credsMap.get( simpleUser ) == null )
+ {
+ credsMap.put( simpleUser, new ArrayList<UserCred>() );
+
+ UserCred newEntry = new UserCred();
+ newEntry.user = user;
+ newEntry.ns = ns;
+
+ credsMap.get( simpleUser ).add( newEntry );
+ }
+ else
+ {
+ UserCred newEntry = new UserCred();
+ newEntry.user = user;
+ newEntry.ns = ns;
+
+ credsMap.get( simpleUser ).add( newEntry );
+ }
+
+ env.debug().log( String.format( "\tUser: %s NS: %s", user, ns ) );
+ }
+ }
+
+ public void loadUsersFromRoles()
+ {
+ String query = "select user,role from authz.user_role" ;
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ ResultSet results = session.execute(stmt);
+ int total=0, flagged=0;
+
+ Iterator<Row> iter = results.iterator();
+ while( iter.hasNext() )
+ {
+ Row row = iter.next();
+ String user = row.getString( "user" );
+ String role = row.getString( "role" );
+ String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+ if ( isMechID( simpleUser ) )
+ {
+ continue;
+ }
+ else if ( rolesMap.get( simpleUser ) == null )
+ {
+ rolesMap.put( simpleUser, new ArrayList<UserRole>() );
+
+ UserRole newEntry = new UserRole();
+ newEntry.user = user;
+ newEntry.role = role;
+
+ rolesMap.get( simpleUser ).add( newEntry );
+ }
+ else
+ {
+ UserRole newEntry = new UserRole();
+ newEntry.user = user;
+ newEntry.role = role;
+
+ rolesMap.get( simpleUser ).add( newEntry );
+ }
+
+ env.debug().log( String.format( "\tUser: %s Role: %s", user, role ) );
+
+ ++total;
+ }
+ env.info().log( String.format( "rows read: %d expiring: %d", total, flagged ) );
+ }
+
+ public void loadOwnersFromNS()
+ {
+ String query = "select name,admin,responsible from authz.ns" ;
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ ResultSet results = session.execute(stmt);
+
+ Iterator<Row> iter = results.iterator();
+ while( iter.hasNext() )
+ {
+ Row row = iter.next();
+ Set<String> responsibles = row.getSet( "responsible", String.class );
+
+ for ( String user : responsibles )
+ {
+ env.info().log( String.format( "Found responsible %s", user ) );
+ String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+ if ( isMechID( simpleUser ) )
+ {
+ continue;
+ }
+ else if ( ownersMap.get( simpleUser ) == null )
+ {
+ ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
+
+ NamespaceOwner newEntry = new NamespaceOwner();
+ newEntry.user = user;
+ newEntry.ns = row.getString( "name" );
+ newEntry.ownerCount = responsibles.size();
+ newEntry.responsible = true;
+ ownersMap.get( simpleUser ).add( newEntry );
+ }
+ else
+ {
+ NamespaceOwner newEntry = new NamespaceOwner();
+ newEntry.user = user;
+ newEntry.ns = row.getString( "name" );
+ newEntry.ownerCount = responsibles.size();
+ newEntry.responsible = true;
+ ownersMap.get( simpleUser ).add( newEntry );
+ }
+ }
+ Set<String> admins = row.getSet( "admin", String.class );
+
+ for ( String user : admins )
+ {
+ env.info().log( String.format( "Found admin %s", user ) );
+ String simpleUser = user.substring( 0, user.indexOf( "@" ) );
+
+ if ( isMechID( simpleUser ) )
+ {
+ continue;
+ }
+ else if ( ownersMap.get( simpleUser ) == null )
+ {
+ ownersMap.put( simpleUser, new ArrayList<NamespaceOwner>() );
+
+ NamespaceOwner newEntry = new NamespaceOwner();
+ newEntry.user = user;
+ newEntry.ns = row.getString( "name" );
+ newEntry.responsible = false;
+ newEntry.ownerCount = -1; //
+ ownersMap.get( simpleUser ).add( newEntry );
+ }
+ else
+ {
+ NamespaceOwner newEntry = new NamespaceOwner();
+ newEntry.user = user;
+ newEntry.ns = row.getString( "name" );
+ newEntry.responsible = false;
+ newEntry.ownerCount = -1; //
+ ownersMap.get( simpleUser ).add( newEntry );
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Processes the specified JobChange data file obtained from Webphone. Each line is
+ * read and processed and any fallout is written to the specified fallout file.
+ * If fallout file already exists it is deleted and a new one is created. A
+ * comparison of the supervisor id in the job data file is done against the one returned
+ * by the authz service and if the supervisor Id has changed then the record is updated
+ * using the authz service. An email is sent to the new supervisor to approve the roles
+ * assigned to the user.
+ *
+ * @param fileName - name of the file to process including its path
+ * @param falloutFileName - the file where the fallout entries have to be written
+ * @param validDate - the valid effective date when the user had moved to the new supervisor
+ * @throws Exception
+ */
+ public void processJobChangeDataFile(String fileName,
+ String falloutFileName, Date validDate) throws Exception
+ {
+
+ BufferedWriter writer = null;
+
+ try {
+
+ env.info().log("Reading file: " + fileName );
+
+ FileInputStream fstream = new FileInputStream(fileName);
+ BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
+
+ String strLine;
+
+ while ((strLine = br.readLine()) != null) {
+ processLine( strLine, writer );
+ }
+
+ br.close();
+
+
+ } catch (IOException e) {
+ env.error().log( "Error while reading from the input data file: " + e );
+ throw e;
+ }
+ }
+
+ public void handleAdminChange( String user )
+ {
+ ArrayList<NamespaceOwner> val = ownersMap.get( user );
+
+ for ( NamespaceOwner r : val )
+ {
+ env.info().log( "handleAdminChange: " + user );
+ AuthzTrans trans = env.newTransNoAvg();
+
+
+ if ( r.responsible )
+ {
+ env.info().log( String.format( "delete from NS owner: %s, NS: %s, count: %s",
+ r.user, r.ns, r.ownerCount ) );
+
+ aspr.info( String.format( "action=DELETE_NS_OWNER, user=%s, ns=%s",
+ r.user, r.ns ) );
+ if ( r.ownerCount < 2 )
+ {
+ // send warning email to aaf-support, after this deletion, no owner for NS
+ ArrayList<String> toAddress = new ArrayList<String>();
+ toAddress.add( "XXX_EMAIL" );
+
+ env.warn().log( "removing last owner from namespace" );
+
+ Organization org = null;
+ org = getOrgFromID( myTrans, org, toAddress.get(0) );
+
+ env.info().log( "calling getOrgFromID with " + toAddress.get(0) );
+
+ if ( org != null )
+ {
+ try
+ {
+ aspr.info( String.format( "action=EMAIL_NO_OWNER_NS to=%s, user=%s, ns=%s",
+ toAddress.get(0), r.user, r.ns ) );
+ org.sendEmail( trans, toAddress,
+ new ArrayList<String>(),
+ String.format( "WARNING: no owners for AAF namespace '%s'", r.ns ), // subject:
+ String.format( "AAF recieved a jobchange notification for user %s who was the owner of the '%s' namespace. Please identify a new owner for this namespace and update AAF.", r.user, r.ns ), // body of msg
+ true );
+ } catch (Exception e) {
+ env.error().log("calling sendEmail()");
+
+ e.printStackTrace();
+ }
+ }
+ else
+ {
+ env.error().log( "Failed getOrgFromID" );
+ }
+ }
+ }
+ else
+ {
+ env.info().log( String.format( "delete from NS admin: %s, NS: %s",
+ r.user, r.ns ) );
+
+ aspr.info( String.format( "action=DELETE_NS_ADMIN, user=%s, ns=%s",
+ r.user, r.ns ) );
+ }
+
+ String field = (r.responsible == true) ? "responsible" : "admin";
+
+ String query = String.format( "update authz.ns set %s = %s - {'%s'} where name = '%s'",
+ field, field, r.user, r.ns ) ;
+ env.info().log( "query: " + query );
+ Statement stmt = new SimpleStatement( query );
+ /*Row row = */session.execute(stmt).one();
+
+ String attribQuery = String.format( "delete from authz.ns_attrib where ns = '%s' AND type='%s' AND name='%s'",
+ r.ns, field, r.user);
+ env.info().log( "ns_attrib query: " + attribQuery);
+ Statement attribStmt = new SimpleStatement( attribQuery );
+ /*Row attribRow = */session.execute(attribStmt).one();
+
+ }
+ }
+
+ public void handleRoleChange( String user )
+ {
+ ArrayList<UserRole> val = rolesMap.get( user );
+
+ for ( UserRole r : val )
+ {
+ env.info().log( "handleRoleChange: " + user );
+
+ env.info().log( String.format( "delete from %s from user_role: %s",
+ r.user, r.role ) );
+
+ aspr.info( String.format( "action=DELETE_FROM_ROLE, user=%s, role=%s",
+ r.user, r.role ) );
+
+
+ String query = String.format( "delete from authz.user_role where user = '%s' and role = '%s'",
+ r.user, r.role );
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ /* Row row = */ session.execute(stmt).one();
+
+ }
+ }
+
+ public void handleCredChange( String user )
+ {
+ ArrayList<UserCred> val = credsMap.get( user );
+
+ for ( UserCred r : val )
+ {
+ env.info().log( "handleCredChange: " + user );
+
+ env.info().log( String.format( "delete user %s cred from ns: %s",
+ r.user, r.ns ) );
+
+ aspr.info( String.format( "action=DELETE_FROM_CRED, user=%s, ns=%s",
+ r.user, r.ns ) );
+
+ String query = String.format( "delete from authz.cred where id = '%s'",
+ r.user );
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ /*Row row = */session.execute(stmt).one();
+
+ }
+
+ }
+
+ public boolean processLine(String line, BufferedWriter writer) throws IOException
+ {
+ SimpleDateFormat sdfDate = new SimpleDateFormat("yyyyMMdd");
+ boolean errorFlag = false;
+ String errorMsg = "";
+
+ try
+ {
+ String[] phoneInfo = line.split( "\\|" );
+
+ if ((phoneInfo != null) && (phoneInfo.length >= 8)
+ && (!phoneInfo[0].startsWith("#")))
+ {
+ String user = phoneInfo[0];
+ String newSupervisor = phoneInfo[7];
+ Date effectiveDate = sdfDate.parse(phoneInfo[8].trim());
+
+ env.debug().log( String.format( "checking user: %s, newSupervisor: %s, date: %s",
+ user, newSupervisor, effectiveDate ) );
+
+ // Most important case, user is owner of a namespace
+ //
+ if ( ownersMap.get( user ) != null )
+ {
+ env.info().log( String.format( "Found %s as a namespace admin/owner", user ) );
+ handleAdminChange( user );
+ }
+
+ if ( credsMap.get( user ) != null )
+ {
+ env.info().log( String.format( "Found %s in cred table", user ) );
+ handleCredChange( user );
+ }
+
+ if ( rolesMap.get( user ) != null )
+ {
+ env.info().log( String.format( "Found %s in a role ", user ) );
+ handleRoleChange( user );
+ }
+ }
+
+ else if (phoneInfo[0].startsWith("#"))
+ {
+ return true;
+ }
+ else
+ {
+ env.warn().log("Can't parse. Skipping the line." + line);
+ errorFlag = true;
+ }
+ } catch (Exception e) {
+ errorFlag = true;
+ errorMsg = e.getMessage();
+ env.error().log( "Error while processing line:" + line + e );
+ e.printStackTrace();
+ } finally {
+ if (errorFlag) {
+ env.info().log( "Fallout enrty being written for line:" + line );
+ writer.write(line + "|Failed to update supervisor for user:" + errorMsg + "\n");
+ }
+ }
+ return true;
+ }
+
+
+ public JobChange(AuthzTrans trans) throws APIException, IOException {
+ super( trans.env() );
+ myTrans = trans;
+ session = cluster.connect();
+ }
+
+ public Organization getOrgFromID( AuthzTrans trans, Organization _org, String user ) {
+ Organization org = _org;
+ if ( org == null || ! user.endsWith( org.getRealm() ) ) {
+ int idx = user.lastIndexOf('.');
+ if ( idx > 0 )
+ idx = user.lastIndexOf( '.', idx-1 );
+
+ org = null;
+ if ( idx > 0 ) {
+ try {
+ org = OrganizationFactory.obtain( trans.env(), user.substring( idx+1 ) );
+ } catch (Exception e) {
+ trans.error().log(e,"Failure Obtaining Organization");
+ }
+ }
+
+ 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 void dumpOwnersMap()
+ {
+ for ( Map.Entry<String, ArrayList<NamespaceOwner>> e : ownersMap.entrySet() )
+ {
+ String key = e.getKey();
+ ArrayList<NamespaceOwner> values = e.getValue();
+
+ env.info().log( "ns user: " + key );
+
+ for ( NamespaceOwner r : values )
+ {
+ env.info().log( String.format( "\tNS-user: %s, NS-name: %s, ownerCount: %d",
+ r.user, r.ns, r.ownerCount ) );
+
+ }
+ }
+ }
+
+ public void dumpRolesMap()
+ {
+ for ( Map.Entry<String, ArrayList<UserRole>> e : rolesMap.entrySet() )
+ {
+ String key = e.getKey();
+ ArrayList<UserRole> values = e.getValue();
+
+ env.info().log( "user: " + key );
+
+ for ( UserRole r : values )
+ {
+ env.info().log( String.format( "\trole-user: %s, role-name: %s",
+ r.user, r.role ) );
+ }
+ }
+ }
+ public void dumpCredMap()
+ {
+ for ( Map.Entry<String, ArrayList<UserCred>> e : credsMap.entrySet() )
+ {
+ String key = e.getKey();
+ ArrayList<UserCred> values = e.getValue();
+
+ env.info().log( "user: " + key );
+
+ for ( UserCred r : values )
+ {
+ env.info().log( String.format( "\tcred-user: %s, ns: %s",
+ r.user, r.ns ) );
+ }
+
+ }
+ }
+
+ @Override
+ protected void run (AuthzTrans trans)
+ {
+ if ( acquireRunLock( this.getClass().getName() ) != 1 ) {
+ env.warn().log( "Cannot acquire run lock, exiting" );
+ System.exit( 1 );
+ }
+
+ try {
+// Map<String,EmailMsg> email = new HashMap<String,EmailMsg>();
+
+ try
+ {
+ String workingDir = System.getProperty("user.dir");
+ env.info().log( "Process jobchange file. PWD is " + workingDir );
+
+ loadUsersFromRoles();
+ loadOwnersFromNS();
+ loadUsersFromCred();
+
+ dumpRolesMap();
+ dumpOwnersMap();
+ dumpCredMap();
+
+ String fname = getJobChangeDataFile();
+
+ if ( fname == null )
+ {
+ env.warn().log("getJobChangedatafile returned null");
+ }
+ else
+ {
+ env.info().log("done with FTP");
+ }
+ processJobChangeDataFile( fname, "fallout", null );
+ }
+ catch (Exception e)
+ {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+
+/*
+ private class EmailMsg {
+ private boolean urgent = false;
+ public String url;
+ public Organization org;
+ public String summary;
+
+ public EmailMsg() {
+ org = null;
+ summary = "";
+ }
+
+ public boolean getUrgent() {
+ return( this.urgent );
+ }
+
+ public void setUrgent( boolean val ) {
+ this.urgent = val;
+ }
+ public void setOrg( Organization newOrg ) {
+ this.org = newOrg;
+ }
+ public Organization getOrg() {
+ return( this.org );
+ }
+ }
+*/
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ }
+}
+
+
diff --git a/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java
new file mode 100644
index 0000000..df537c2
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/UserRoleDataGeneration.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Random;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.SimpleStatement;
+import com.datastax.driver.core.Statement;
+
+public class UserRoleDataGeneration extends Batch {
+
+ protected UserRoleDataGeneration(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ session = cluster.connect();
+
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+
+ String query = "select * from authz.history" ;
+
+ env.info().log( "query: " + query );
+
+ Statement stmt = new SimpleStatement( query );
+ ResultSet results = session.execute(stmt);
+ int total=0;
+
+ Iterator<Row> iter = results.iterator();
+
+ Random rand = new Random();
+
+ int min = 1;
+ int max = 32;
+
+ while( iter.hasNext() ) {
+ Row row = iter.next();
+ if (row.getString("target").equals("user_role")) {
+ int randomNum = rand.nextInt((max - min) + 1) + min;
+
+ String newId = modifiedTimeuid(row.getUUID("id").toString(), randomNum);
+ String subject = row.getString("subject");
+ String newSubject = subject.split("\\|")[1];
+
+ String newInsert = insertStmt(row, newId, "role", newSubject);
+ Statement statement = new SimpleStatement(newInsert);
+ session.executeAsync(statement);
+
+ total++;
+ }
+ }
+
+ env.info().log(total+ " history elements inserted for user roles");
+
+ }
+
+ private String insertStmt(Row row, String newId, String newTarget, String newSubject) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("INSERT INTO authz.history (id,action,memo,reconstruct,subject,target,user,yr_mon) VALUES (");
+ sb.append(newId+",");
+ sb.append("'"+row.getString("action")+"',");
+ sb.append("'"+row.getString("memo")+"',");
+ sb.append("null,");
+ sb.append("'"+newSubject+"',");
+ sb.append("'"+newTarget+"',");
+ sb.append("'"+row.getString("user")+"',");
+ sb.append(row.getInt("yr_mon"));
+ sb.append(")");
+
+ return sb.toString();
+ }
+
+ private String modifiedTimeuid(String origTimeuuid, int rand) {
+ UUID uuid = UUID.fromString(origTimeuuid);
+
+ long bottomBits = uuid.getLeastSignificantBits();
+ long newBottomBits = bottomBits + (1 << rand);
+ if (newBottomBits - bottomBits == 0)
+ env.info().log("Duplicate!\t"+uuid + " not duplicated for role history function.");
+
+ UUID newUuid = new UUID(uuid.getMostSignificantBits(),newBottomBits);
+ return newUuid.toString();
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info( "End UserRoleDataGeneration processing" );
+
+ }
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Action.java b/authz-batch/src/main/java/com/att/authz/actions/Action.java
new file mode 100644
index 0000000..f69bb22
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Action.java
@@ -0,0 +1,11 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+
+public interface Action<T,RV> {
+ public Result<RV> exec(AuthzTrans trans, T ur);
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java
new file mode 100644
index 0000000..f0d10a8
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/ActionDAO.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.dao.CassAccess;
+import com.att.dao.aaf.hl.Function;
+import com.att.dao.aaf.hl.Question;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.Cluster;
+import com.datastax.driver.core.Session;
+
+public abstract class ActionDAO<T,RV> implements Action<T,RV> {
+ protected final Question q;
+ protected final Function f;
+ private boolean clean;
+
+ public ActionDAO(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ q = new Question(trans, cluster, CassAccess.KEYSPACE, false);
+ f = new Function(trans,q);
+ clean = true;
+ }
+
+ public ActionDAO(AuthzTrans trans, ActionDAO<?,?> predecessor) {
+ q = predecessor.q;
+ f = new Function(trans,q);
+ clean = false;
+ }
+
+ public Session getSession(AuthzTrans trans) throws APIException, IOException {
+ return q.historyDAO.getSession(trans);
+ }
+
+ public void close(AuthzTrans trans) {
+ if(clean) {
+ q.close(trans);
+ }
+ }
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java
new file mode 100644
index 0000000..3f521f1
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/ActionPuntDAO.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.security.SecureRandom;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.inno.env.APIException;
+import com.datastax.driver.core.Cluster;
+
+public abstract class ActionPuntDAO<T, RV> extends ActionDAO<T, RV> {
+ private static final SecureRandom random = new SecureRandom();
+ private int months, range;
+ protected static final Date now = new Date();
+
+ public ActionPuntDAO(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException {
+ super(trans, cluster);
+ 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() {
+ GregorianCalendar temp = new GregorianCalendar();
+ temp.setTime(now);
+ if(range>0) {
+ int forward = months+Math.abs(random.nextInt()%range);
+ temp.add(GregorianCalendar.MONTH, forward);
+ temp.add(GregorianCalendar.DAY_OF_MONTH, (random.nextInt()%30)-15);
+ }
+ return temp.getTime();
+
+ }
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java
new file mode 100644
index 0000000..80c6755
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredDelete.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class CredDelete extends ActionDAO<CredDAO.Data,Void> {
+
+ public CredDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ super(trans, cluster);
+ }
+
+ public CredDelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) {
+ Result<Void> rv = q.credDAO.delete(trans, cred, true); // need to read for undelete
+ trans.info().log("Deleted:",cred.id,CredPrint.type(cred.type),Chrono.dateOnlyStamp(cred.expires));
+ return rv;
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java
new file mode 100644
index 0000000..3e8c294
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredPrint.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class CredPrint implements Action<CredDAO.Data,Void> {
+ private String text;
+
+ public CredPrint(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, CredDAO.Data cred) {
+ trans.info().log(text,cred.id,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/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java
new file mode 100644
index 0000000..0805e9b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/CredPunt.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class CredPunt extends ActionPuntDAO<CredDAO.Data,Void> {
+
+ public CredPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws IOException, APIException {
+ super(trans,cluster,months,range);
+ }
+
+ 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) {
+ 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();
+ if(data.expires.before(from)) {
+ trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+ } else {
+ rv = q.credDAO.update(trans, data);
+ trans.info().log("Updated Cred",cdd.id, CredPrint.type(cdd.type), "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+ }
+ }
+ }
+ if(rv==null) {
+ rv=Result.err(read);
+ }
+ return rv;
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Email.java b/authz-batch/src/main/java/com/att/authz/actions/Email.java
new file mode 100644
index 0000000..df491df
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Email.java
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+
+public class Email implements Action<Organization,Void>{
+ 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=" ";
+
+
+ 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(Collection<String> users) {
+ toList.addAll(users);
+ return this;
+ }
+
+ public Email addTo(String email) {
+ toList.add(email);
+ return this;
+ }
+
+
+ public Email subject(String format, Object ... args) {
+ subject = String.format(format, args);
+ 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) {
+ 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");
+ }
+
+ 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();
+
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java
new file mode 100644
index 0000000..5b356ce
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/EmailPrint.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.PrintStream;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+
+public class EmailPrint extends Email {
+
+ public EmailPrint(String... defaultCC) {
+ super(defaultCC);
+ }
+
+ /* (non-Javadoc)
+ * @see com.att.authz.actions.Email#exec(com.att.authz.org.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();
+
+ out.println(msg);
+ return Result.ok();
+
+ }
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/FADelete.java b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java
new file mode 100644
index 0000000..b61ac7d
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/FADelete.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Future;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.ApprovalDAO;
+import com.att.dao.aaf.cass.FutureDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class FADelete extends ActionDAO<Future,Void> {
+ public FADelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ super(trans, cluster);
+ }
+
+ public FADelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Future f) {
+ FutureDAO.Data fdd = new FutureDAO.Data();
+ fdd.id=f.id;
+ Result<Void> rv = q.futureDAO.delete(trans, fdd, true); // need to read for undelete
+ if(rv.isOK()) {
+ trans.info().log("Deleted:",f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires));
+ } else {
+ trans.info().log("Failed to Delete Approval");
+ }
+
+ Result<List<ApprovalDAO.Data>> ral = q.approvalDAO.readByTicket(trans, f.id);
+ if(ral.isOKhasData()) {
+ for(ApprovalDAO.Data add : ral.value) {
+ rv = q.approvalDAO.delete(trans, add, false);
+ if(rv.isOK()) {
+ trans.info().log("Deleted: Approval",add.id,"on ticket",add.ticket,"for",add.approver);
+ } else {
+ trans.info().log("Failed to Delete Approval");
+ }
+ }
+ }
+ return rv;
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java
new file mode 100644
index 0000000..c2ec50a
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/FAPrint.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Future;
+import com.att.authz.layer.Result;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class FAPrint implements Action<Future,Void> {
+ private String text;
+
+ public FAPrint(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, Future f) {
+ trans.info().log(text,f.id,f.memo,"expiring on",Chrono.dateOnlyStamp(f.expires));
+ return Result.ok();
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Key.java b/authz-batch/src/main/java/com/att/authz/actions/Key.java
new file mode 100644
index 0000000..89b7c6f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Key.java
@@ -0,0 +1,8 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+public interface Key<HELPER> {
+ public String key(HELPER H);
+}
diff --git a/authz-batch/src/main/java/com/att/authz/actions/Message.java b/authz-batch/src/main/java/com/att/authz/actions/Message.java
new file mode 100644
index 0000000..2aca4ea
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/Message.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.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 void line(String format, Object ... args) {
+ lines.add(String.format(format, args));
+ }
+
+ 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/authz-batch/src/main/java/com/att/authz/actions/URAdd.java b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java
new file mode 100644
index 0000000..fd3962f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URAdd.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import com.att.dao.aaf.cass.UserRoleDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URAdd extends ActionDAO<UserRole,UserRoleDAO.Data> {
+ public URAdd(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ super(trans, cluster);
+ }
+
+ public URAdd(AuthzTrans trans, ActionDAO<?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Data> exec(AuthzTrans trans, UserRole ur) {
+ UserRoleDAO.Data urd = new UserRoleDAO.Data();
+ urd.user = ur.user;
+ urd.role = ur.role;
+ urd.ns=ur.ns;
+ urd.rname = ur.rname;
+ urd.expires = ur.expires;
+ Result<Data> rv = q.userRoleDAO.create(trans, urd);
+ trans.info().log("Added:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires));
+ return rv;
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URDelete.java b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java
new file mode 100644
index 0000000..e3bd40a
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URDelete.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URDelete extends ActionDAO<UserRole,Void> {
+ public URDelete(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ super(trans, cluster);
+ }
+
+ public URDelete(AuthzTrans trans, ActionDAO<?,?> adao) {
+ super(trans, adao);
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+ UserRoleDAO.Data urd = new UserRoleDAO.Data();
+ urd.user = ur.user;
+ urd.role = ur.role;
+ Result<Void> rv = q.userRoleDAO.delete(trans, urd, true); // need to read for undelete
+ trans.info().log("Deleted:",ur.role,ur.user,"on",Chrono.dateOnlyStamp(ur.expires));
+ return rv;
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java
new file mode 100644
index 0000000..6af3e12
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URFutureApprove.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Expiration;
+import com.att.authz.org.Organization.Identity;
+import com.att.dao.aaf.cass.FutureDAO;
+import com.att.dao.aaf.cass.NsDAO;
+import com.att.dao.aaf.hl.Function;
+import com.att.dao.aaf.hl.Question;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URFutureApprove extends ActionDAO<UserRole, List<Identity>> implements Action<UserRole,List<Identity>>, Key<UserRole> {
+ private final Date start, expires;
+
+ public URFutureApprove(AuthzTrans trans, Cluster cluster) throws APIException, IOException {
+ super(trans,cluster);
+ 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<List<Identity>> exec(AuthzTrans trans, UserRole ur) {
+ 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 = expires;
+ try {
+ data.construct = ur.to().bytify();
+ } catch (IOException e) {
+ return Result.err(e);
+ }
+ Result<List<Identity>> rapprovers = f.createFuture(trans, data, Function.FOP_USER_ROLE, ur.user, rns.value, "U");
+ return rapprovers;
+ } 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 "Re-Validate Ownership for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires);
+ } else if(Question.ADMIN.equals(ur.rname)) {
+ return "Re-Validate as Administrator for AAF Namespace '" + ur.ns + expire + Chrono.dateOnlyStamp(ur.expires);
+ } else {
+ return "Re-Approval in Role '" + ur.role + expire + Chrono.dateOnlyStamp(ur.expires);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java
new file mode 100644
index 0000000..ea5a8bf
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URFuturePrint.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Identity;
+import org.onap.aaf.inno.env.util.Chrono;
+
+
+public class URFuturePrint implements Action<UserRole,List<Identity>> {
+ private String text;
+ private final static List<Identity> rv = new ArrayList<Identity>();
+
+ public URFuturePrint(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public Result<List<Identity>> exec(AuthzTrans trans, UserRole ur) {
+ trans.info().log(text,ur.user,"to",ur.role,"on",Chrono.dateOnlyStamp(ur.expires));
+ return Result.ok(rv);
+ }}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPrint.java b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java
new file mode 100644
index 0000000..8092567
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URPrint.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class URPrint implements Action<UserRole,Void> {
+ private String text;
+
+ public URPrint(String text) {
+ this.text = text;
+ }
+
+ @Override
+ public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+ trans.info().log(text,ur.user,"to",ur.role,"expiring on",Chrono.dateOnlyStamp(ur.expires));
+ return Result.ok();
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/actions/URPunt.java b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java
new file mode 100644
index 0000000..e76852f
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/actions/URPunt.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.actions;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.dao.aaf.cass.UserRoleDAO;
+import com.att.dao.aaf.cass.UserRoleDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.datastax.driver.core.Cluster;
+
+public class URPunt extends ActionPuntDAO<UserRole,Void> {
+ public URPunt(AuthzTrans trans, Cluster cluster, int months, int range) throws APIException, IOException {
+ super(trans,cluster, months, range);
+ }
+
+ public URPunt(AuthzTrans trans, ActionDAO<?,?> adao, int months, int range) {
+ super(trans, adao, months, range);
+ }
+
+ public Result<Void> exec(AuthzTrans trans, UserRole ur) {
+ 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();
+ if(data.expires.before(from)) {
+ trans.error().printf("Error: %s is before %s", Chrono.dateOnlyStamp(data.expires), Chrono.dateOnlyStamp(from));
+ } else {
+ q.userRoleDAO.update(trans, data);
+ trans.info().log("Updated User",ur.user,"and Role", ur.role, "from",Chrono.dateOnlyStamp(from),"to",Chrono.dateOnlyStamp(data.expires));
+ }
+ }
+ return Result.ok();
+ } else {
+ return Result.err(read);
+ }
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java
new file mode 100644
index 0000000..4f05f20
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/AafEntryConverter.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.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/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java
new file mode 100644
index 0000000..96c8812
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/CredEntryConverter.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import com.att.dao.aaf.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/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java
new file mode 100644
index 0000000..e9cd91c
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/NsEntryConverter.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.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;
+ // JG 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/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java
new file mode 100644
index 0000000..afabdfd
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/PermEntryConverter.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.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/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java
new file mode 100644
index 0000000..51389bd
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/RoleEntryConverter.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import com.att.dao.aaf.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/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java
new file mode 100644
index 0000000..0b2a956
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/entryConverters/UserRoleEntryConverter.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.entryConverters;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import com.att.dao.aaf.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/authz-batch/src/main/java/com/att/authz/helpers/Approver.java b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java
new file mode 100644
index 0000000..0cac97b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Approver.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.att.authz.actions.Message;
+import com.att.authz.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/authz-batch/src/main/java/com/att/authz/helpers/Creator.java b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java
new file mode 100644
index 0000000..1fe513e
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Creator.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.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/authz-batch/src/main/java/com/att/authz/helpers/Cred.java b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java
new file mode 100644
index 0000000..a7717ae
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Cred.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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 final String id;
+ public final List<Instance> instances;
+
+ public Cred(String id) {
+ this.id = id;
+ instances = new ArrayList<Instance>();
+ }
+
+ public static class Instance {
+ public final int type;
+ public final Date expires;
+ public final Integer other;
+
+ public Instance(int type, Date expires, Integer other) {
+ this.type = type;
+ this.expires = expires;
+ this.other = other;
+ }
+ }
+
+ public Date last(final int type) {
+ Date last = null;
+ for(Instance i : instances) {
+ if(i.type==type && (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 ) {
+ load(trans, session,"select id, type, expires, other from authz.cred;");
+
+ }
+
+ public static void loadOneNS(Trans trans, Session session, String ns ) {
+ load(trans, session,"select id, type, expires, other from authz.cred WHERE ns='" + ns + "';");
+ }
+
+ private static void load(Trans trans, Session session, String query) {
+
+ 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;
+ tt = trans.start("Load Roles", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ ++count;
+ row = iter.next();
+ String id = row.getString(0);
+ Cred cred = data.get(id);
+ if(cred==null) {
+ cred = new Cred(id);
+ data.put(id, cred);
+ }
+ cred.instances.add(new Instance(row.getInt(1), row.getDate(2), row.getInt(3)));
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",count,"creds");
+ }
+
+
+ }
+ 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/authz-batch/src/main/java/com/att/authz/helpers/Future.java b/authz-batch/src/main/java/com/att/authz/helpers/Future.java
new file mode 100644
index 0000000..d658535
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Future.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.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.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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 Future {
+ public static final List<Future> data = new ArrayList<Future>();
+ public static final TreeMap<String,List<Future>> byMemo = new TreeMap<String,List<Future>>();
+
+ public final UUID id;
+ public final String memo, target;
+ public final Date start, expires;
+ public Future(UUID id, String memo, String target, Date start, Date expires) {
+ this.id = id;
+ this.memo = memo;
+ this.target = target;
+ this.start = start;
+ this.expires = expires;
+ }
+
+ 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.add(f);
+
+ List<Future> lf = byMemo.get(f.memo);
+ if(lf == null) {
+ lf = new ArrayList<Future>();
+ byMemo.put(f.memo, lf);
+ }
+ lf.add(f);
+
+ }
+ } finally {
+ trans.info().log("Found",count,"Futures");
+ }
+ }
+
+ public static Creator<Future> v2_0_15 = new Creator<Future>() {
+ @Override
+ public Future create(Row row) {
+ return new Future(row.getUUID(0),row.getString(1),row.getString(2),
+ row.getDate(3),row.getDate(4));
+ }
+
+ @Override
+ public String select() {
+ return "select id,memo,target,start,expires from authz.future";
+ }
+ };
+
+ public static void delete(List<Future> fl) {
+ if(fl==null || fl.isEmpty()) {
+ return;
+ }
+ for(Future f : fl) {
+ data.remove(f);
+ }
+ // Faster to start over, then look for entries.
+ byMemo.clear();
+ for(Future f : data) {
+ List<Future> lf = byMemo.get(f.memo);
+ if(lf == null) {
+ lf = new ArrayList<Future>();
+ byMemo.put(f.memo, lf);
+ }
+ lf.add(f);
+ }
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java
new file mode 100644
index 0000000..02fdc16
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/InputIterator.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.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/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java
new file mode 100644
index 0000000..b553009
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/MiscID.java
@@ -0,0 +1,169 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.att.authz.BatchException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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/authz-batch/src/main/java/com/att/authz/helpers/NS.java b/authz-batch/src/main/java/com/att/authz/helpers/NS.java
new file mode 100644
index 0000000..f8c5975
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/NS.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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 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/authz-batch/src/main/java/com/att/authz/helpers/Notification.java b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java
new file mode 100644
index 0000000..501edfa
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Notification.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.TreeMap;
+
+import com.att.authz.actions.Message;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.org.EmailWarnings;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Notify;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.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 static final TreeMap<String,List<Notification>> data = new TreeMap<String,List<Notification>>();
+ public static final long now = System.currentTimeMillis();
+
+ public final String user;
+ public final Notify type;
+ public final Date last;
+ public final int checksum;
+ public Message msg;
+ private int current;
+ public Organization org;
+ public int count;
+ private long graceEnds,lastdays;
+
+ private Notification(String user, int type, Date last, int checksum) {
+ this.user = user;
+ this.type = Notify.from(type);
+ this.last = last;
+ this.checksum = checksum;
+ current = 0;
+ count = 0;
+ }
+
+ private Notification(String user, Notify type, Date last, int checksum) {
+ this.user = user;
+ this.type = type;
+ 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, Notify type) {
+ List<Notification> ln = data.get(user);
+ if(ln!=null) {
+ for(Notification n : ln) {
+ if(type.equals(n.type)) {
+ return n;
+ }
+ }
+ }
+ return null;
+ }
+
+ private static Notification getOrCreate(String user, Notify type) {
+ List<Notification> ln = data.get(user);
+ Notification n = null;
+ if(ln==null) {
+ ln = new ArrayList<Notification>();
+ data.put(user, ln);
+ } else {
+ for(Notification n2 : ln) {
+ if(type.equals(n2.type)) {
+ n=n2;
+ break;
+ }
+ }
+ }
+ if(n==null) {
+ n = new Notification(user, type, new Date(), 0);
+ ln.add(n);
+ }
+ return n;
+ }
+
+ public static Notification add(AuthzTrans trans, UserRole ur) {
+ Notification n = getOrCreate(ur.user,Notify.RoleExpiration);
+ if(n.org==null) {
+ try {
+ n.org = OrganizationFactory.obtain(trans.env(), ur.ns);
+ } catch (OrganizationException e) {
+ trans.error().log(ur.ns, " does not have a Namespace");
+ }
+ }
+
+ if(n.count==0) {
+ EmailWarnings ew = n.org.emailWarningPolicy();
+ n.graceEnds = ew.roleEmailInterval();
+ n.lastdays = ew.emailUrgentWarning();
+ }
+ ++n.count;
+
+ /*
+ StringBuilder sb = new StringBuilder();
+ sb.append("ID: ");
+ sb.append(ur.user);
+ User ouser;
+ try {
+ ouser = n.org.getUser(trans, ur.user);
+ if(ouser!=null) {
+ sb.append(" (");
+ sb.append(ouser.fullName());
+ sb.append(')');
+ }
+ } catch (Exception e) {
+ }
+ sb.append(" Role: ");
+ sb.append(ur.role);
+ sb.append(" Expire");
+ if(now<ur.expires.getTime()) {
+ sb.append("s: ");
+ } else {
+ sb.append("d: ");
+ }
+ sb.append(Chrono.dateOnlyStamp(ur.expires));
+ sb.append("\n If you wish to extend, type\n");
+ sb.append("\trole user extend ");
+ sb.append(ur.role);
+ sb.append(' ');
+ sb.append(ur.user);
+ sb.append("\n If you wish to delete, type\n");
+ sb.append("\trole user del ");
+ sb.append(ur.role);
+ sb.append(' ');
+ sb.append(ur.user);
+ sb.append('\n');
+ n.msg.add(sb.toString());
+ n.current=0;
+ */
+ return n;
+ }
+
+ public static Notification addApproval(AuthzTrans trans, Identity ou) {
+ Notification n = getOrCreate(ou.id(),Notify.Approval);
+ if(n.org==null) {
+ n.org = ou.org();
+ }
+ if(n.count==0) { // first time.
+ EmailWarnings ew = n.org.emailWarningPolicy();
+ n.graceEnds = ew.apprEmailInterval();
+ n.lastdays = ew.emailUrgentWarning();
+ }
+ ++n.count;
+ return n;
+ }
+
+ public static Creator<Notification> v2_0_14 = new Creator<Notification>() {
+ @Override
+ public Notification create(Row row) {
+ return new Notification(row.getString(0), row.getInt(1), row.getDate(2),row.getInt(3));
+ }
+
+ @Override
+ public String select() {
+ return "select user,type,last,checksum from authz.notify";
+ }
+ };
+
+ public void set(Message msg) {
+ this.msg = msg;
+ }
+
+ public int checksum() {
+ 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) {
+ String update = update();
+ if(update!=null) {
+ if(dryRun) {
+ trans.info().log(update);
+ } else {
+ session.execute(update);
+ }
+ return true; // Updated info, expect to notify
+ }
+ return false;
+ }
+
+ /**
+ * Returns an Update String for CQL if there is data.
+ *
+ * Returns null if nothing to update
+ * @return
+ */
+ private String update() {
+ // If this has been done before, there is no change in checkSum and the last time notified is within GracePeriod
+ if(checksum!=0 && checksum()==checksum && now < last.getTime()+graceEnds && now > last.getTime()+lastdays) {
+ return null;
+ } else {
+ return "UPDATE authz.notify SET last = '" +
+ Chrono.dateOnlyStamp(last) +
+ "', checksum=" +
+ current +
+ " WHERE user='" +
+ user +
+ "' AND type=" +
+ type.getValue() +
+ ";";
+ }
+ }
+
+// public void text(Email email) {
+// for(String s : msg) {
+// email.line(s);
+// }
+// }
+//
+ public String toString() {
+ return "\"" + user + "\",\"" + type.name() + "\",\"" + Chrono.dateOnlyStamp(last);
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java
new file mode 100644
index 0000000..fa0bd28
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/NsAttrib.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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/authz-batch/src/main/java/com/att/authz/helpers/Perm.java b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java
new file mode 100644
index 0000000..41c41a8
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Perm.java
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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>();
+
+ 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 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());
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/Role.java b/authz-batch/src/main/java/com/att/authz/helpers/Role.java
new file mode 100644
index 0000000..fd57f5c
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/Role.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.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 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);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",data.size(),"roles");
+ }
+
+
+ }
+ 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('|', '.');
+ }
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java
new file mode 100644
index 0000000..fa23d13
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/helpers/UserRole.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.helpers;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+import com.att.dao.aaf.cass.UserRoleDAO;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.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 {
+ 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>>();
+
+ public final String user, role, ns, rname;
+ public final Date expires;
+
+ public UserRole(String user, String ns, String rname, Date expires) {
+ this.user = user;
+ this.role = ns + '.' + rname;
+ this.ns = ns;
+ this.rname = rname;
+ this.expires = expires;
+ }
+
+ public UserRole(String user, String role, String ns, String rname, Date expires) {
+ this.user = user;
+ this.role = role;
+ this.ns = ns;
+ this.rname = rname;
+ this.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();
+ }
+ int count = 0;
+ try {
+ Iterator<Row> iter = results.iterator();
+ Row row;
+ tt = trans.start("Load UserRole", Env.SUB);
+ try {
+ while(iter.hasNext()) {
+ ++count;
+ row = iter.next();
+ UserRole ur = creator.create(row);
+ data.add(ur);
+
+ List<UserRole> lur = byUser.get(ur.user);
+ if(lur==null) {
+ lur = new ArrayList<UserRole>();
+ byUser.put(ur.user, lur);
+ }
+ lur.add(ur);
+
+ lur = byRole.get(ur.role);
+ if(lur==null) {
+ lur = new ArrayList<UserRole>();
+ byRole.put(ur.role, lur);
+ }
+ lur.add(ur);
+ }
+ } finally {
+ tt.done();
+ }
+ } finally {
+ trans.info().log("Found",count,"UserRoles");
+ }
+
+
+ }
+
+ 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.getDate(4));
+ }
+
+ @Override
+ public String select() {
+ return "select user,role,ns,rname,expires from authz.user_role";
+ }
+ };
+
+ public UserRoleDAO.Data to() {
+ UserRoleDAO.Data urd = new UserRoleDAO.Data();
+ urd.user = user;
+ urd.role = role;
+ urd.ns = ns;
+ urd.rname = rname;
+ urd.expires = expires;
+ return urd;
+ }
+
+ public String toString() {
+ return "\"" + user + "\",\"" + role + "\",\"" + ns + "\",\"" + rname + "\",\""+ Chrono.dateOnlyStamp(expires);
+ }
+
+}
\ No newline at end of file
diff --git a/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java
new file mode 100644
index 0000000..79bdb5b
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/ApprNotify.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import com.att.authz.Batch;
+import com.att.authz.actions.Email;
+import com.att.authz.actions.Message;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Approver;
+import com.att.authz.helpers.Notification;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationException;
+import com.att.authz.org.OrganizationFactory;
+import com.att.dao.CassAccess;
+import com.att.dao.aaf.cass.ApprovalDAO;
+import com.att.dao.aaf.cass.ApprovalDAO.Data;
+import org.onap.aaf.inno.env.APIException;
+
+public class ApprNotify extends Batch {
+ private final ApprovalDAO apprDAO;
+ private Result<List<Data>> rladd;
+ private Email email;
+
+ public ApprNotify(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ apprDAO = new ApprovalDAO(trans, cluster, CassAccess.KEYSPACE);
+ session = apprDAO.getSession(trans);
+ rladd = apprDAO.readByStatus(trans,"pending");
+ if(isDryRun()) {
+ email = new Email();//EmailPrint();
+ } else {
+ email = new Email();
+ }
+ email.subject("AAF Approval Notification (ENV: %s)",batchEnv);
+ email.preamble("AAF is the AT&T System for Fine-Grained Authorizations. "
+ + "You are being asked to Approve in the %s environment before AAF Actions can be taken. \n\n"
+ + " Please follow this link:\n\n\t%s/approve"
+ ,batchEnv,env.getProperty(GUI_URL));
+
+ Notification.load(trans, session, Notification.v2_0_14);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ if(rladd.isOK()) {
+ if(rladd.isEmpty()) {
+ trans.warn().log("No Pending Approvals to Process");
+ } else {
+ Organization org=null;
+ //Map<String,Organization> users = new HashMap<String,Organization>();
+ Map<String,Approver> users = new TreeMap<String,Approver>();
+
+ for(Data data : rladd.value) {
+ // We've already seen this approver. Simply add the new request to him.
+ try {
+ Approver approver = users.get(data.approver);
+ if(approver==null) {
+ org = OrganizationFactory.obtain(trans.env(), data.approver);
+ approver = new Approver(data.approver, org);
+ users.put(data.approver, approver);
+ }
+ approver.addRequest(data.user);
+ } catch (OrganizationException e) {
+ trans.error().log(e);
+ }
+ }
+
+ // Notify
+ Message msg = new Message();
+ for(Approver approver : users.values()) {
+ try {
+ Notification n = Notification.addApproval(trans, org.getIdentity(trans, approver.name));
+ approver.build(msg);
+ n.set(msg);
+ if(n.update(trans, session, isDryRun())) {
+ Identity user = n.org.getIdentity(trans, approver.name);
+ email.clear();
+ email.addTo(user.email());
+ email.msg(msg);
+ email.exec(trans, n.org);
+ }
+ } catch (OrganizationException e) {
+ trans.error().log(e);
+ }
+ }
+ }
+ } else {
+ trans.error().log('[',rladd.status,']',rladd.details);
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ apprDAO.close(trans);
+ }
+
+
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java
new file mode 100644
index 0000000..58cc074
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckCred.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.Cred.Instance;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+public class CheckCred extends Batch{
+
+ public CheckCred(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+
+ Cred.load(trans, session);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ String query;
+ for(Cred cred : Cred.data.values()) {
+ for(Instance inst : cred.instances) {
+ if(inst.other==0) {
+ if(dryRun) {
+ trans.warn().log("Ensuring 'other' is numeric");
+ } else {
+ query = "UPDATE authz.cred SET other=0 WHERE "
+ + "id='" + cred.id
+ + "' AND type=" + inst.type
+ + " AND expires='" + Chrono.dateStamp(inst.expires)
+ + "';";
+ session.execute(query);
+ trans.warn().log("resetting 'other'",query);
+ }
+ }
+ }
+ }
+
+ }
+ /*
+ /// Evaluate
+ for(UserRole urKey : UserRole.data) {
+ NSSplit nss = NS.deriveParent(urKey.role);
+ if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole
+ if(dryRun) {
+ trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+ } else {
+ query = "DELETE FROM authz.user_role WHERE "
+ + "user='" + urKey.user
+ + "' AND role='" + urKey.role
+ + "';";
+ session.execute(query);
+ trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+ }
+ } else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) {
+ if(dryRun) {
+ trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")");
+ } else {
+ query = "UPDATE authz.user_role SET ns='" + nss.ns
+ + "', rname='" + nss.other
+ + "' WHERE "
+ + "user='" + urKey.user
+ + "' AND role='" + urKey.role
+ + "';";
+ session.execute(query);
+ trans.warn().log("Setting ns and rname",query);
+ }
+ }
+ }
+ }
+ */
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java
new file mode 100644
index 0000000..b4572b4
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckNS.java
@@ -0,0 +1,425 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.NsAttrib;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+import com.att.dao.aaf.cass.NsType;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class CheckNS extends Batch{
+
+ public CheckNS(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+ NS.load(trans, session,NS.v2_0_11);
+ Role.load(trans, session);
+ Perm.load(trans, session);
+ NsAttrib.load(trans, session, NsAttrib.v2_0_11);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+
+ String msg;
+ String query;
+ trans.info().log(STARS, msg = "Checking for NS type mis-match", STARS);
+ TimeTaken tt = trans.start(msg, Env.SUB);
+ try {
+ for(NS ns : NS.data.values()) {
+ if(ns.description==null) {
+ trans.warn().log("Namepace description is null. Changing to empty string.");
+ if(dryRun) {
+ trans.warn().log("Namepace description is null. Changing to empty string");
+ } else {
+ query = "UPDATE authz.ns SET description='' WHERE name='" + ns.name +"';";
+ session.execute(query);
+ }
+ }
+ int scope = count(ns.name,'.');
+ NsType nt;
+ switch(scope) {
+ case 0:
+ nt = NsType.DOT;
+ break;
+ case 1:
+ nt = NsType.ROOT;
+ break;
+ case 2:
+ nt = NsType.COMPANY;
+ break;
+ default:
+ nt = NsType.APP;
+ break;
+ }
+ if(ns.type!=nt.type || ns.scope !=scope) {
+ if(dryRun) {
+ trans.warn().log("Namepace",ns.name,"has no type. Should change to ",nt.name());
+ } else {
+ query = "UPDATE authz.ns SET type=" + nt.type + ", scope=" + scope + " WHERE name='" + ns.name +"';";
+ trans.warn().log("Namepace",ns.name,"changing to",nt.name()+":",query);
+ session.execute(query);
+ }
+ }
+ }
+ } finally {
+ tt.done();
+ }
+
+
+ trans.info().log(STARS, msg = "Checking for NS admin/owner mis-match", STARS);
+ tt = trans.start(msg, Env.SUB);
+ try {
+ /// Evaluate
+ for(NS nk : NS.data.values()) {
+ //String name;
+ String roleAdmin = nk.name+"|admin";
+ String roleAdminPrev = nk.name+".admin";
+ String roleOwner = nk.name+"|owner";
+ String roleOwnerPrev = nk.name+".owner";
+ String permAll = nk.name+"|access|*|*";
+ String permAllPrev = nk.name+".access|*|*";
+ String permRead = nk.name+"|access|*|read";
+ String permReadPrev = nk.name+".access|*|read";
+ // Admins
+
+ Role rk = Role.keys.get(roleAdmin); // accomodate new role key
+ // Role Admin should exist
+ if(rk==null) {
+ if(dryRun) {
+ trans.warn().log(nk.name + " is missing role: " + roleAdmin);
+ } else {
+ query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('"
+ + nk.name
+ + "','admin','Automatic Administration',"
+ + "{'" + nk.name + "|access|*|*'});";
+ session.execute(query);
+ env.info().log(query);
+
+
+ if(Role.keys.get(roleAdminPrev)!=null) {
+ query = "UPDATE authz.role set perms = perms + "
+ + "{'" + roleAdminPrev + "'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='admin'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+ } else {
+ // Role Admin should be linked to Perm All
+ if(!rk.perms.contains(permAll)) {
+ if(dryRun) {
+ trans.warn().log(roleAdmin,"is not linked to",permAll);
+ } else {
+ query = "UPDATE authz.role set perms = perms + "
+ + "{'" + nk.name + "|access|*|*'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='admin'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ if(rk.perms.contains(permAllPrev)) {
+ query = "UPDATE authz.role set perms = perms - "
+ + "{'" + nk.name + ".access|*|*'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='admin'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+ }
+ // Role Admin should not be linked to Perm Read
+ if(rk.perms.contains(permRead)) {
+ if(dryRun) {
+ trans.warn().log(roleAdmin,"should not be linked to",permRead);
+ } else {
+ query = "UPDATE authz.role set perms = perms - "
+ + "{'" + nk.name + "|access|*|read'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='admin'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+ }
+
+ Perm pk = Perm.keys.get(permAll);
+ if(pk==null) {
+ trans.warn().log(nk.name + " is missing perm: " + permAll);
+ if(!dryRun) {
+ query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('"
+ + nk.name
+ + "','access','*','*','Namespace Write',"
+ + "{'" + nk.name + "|admin'});";
+ session.execute(query);
+ env.info().log(query);
+
+ }
+ } else {
+ // PermALL should be linked to Role Admin
+ if(!pk.roles.contains(roleAdmin)) {
+ trans.warn().log(permAll,"is not linked to",roleAdmin);
+ if(!dryRun) {
+ query = "UPDATE authz.perm set roles = roles + "
+ + "{'" + nk.name + "|admin'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='*'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ if(pk.roles.contains(roleAdminPrev)) {
+ query = "UPDATE authz.perm set roles = roles - "
+ + "{'" + nk.name + ".admin'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='*'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ }
+ }
+ }
+
+ // PermALL should be not linked to Role Owner
+ if(pk.roles.contains(roleOwner)) {
+ trans.warn().log(permAll,"should not be linked to",roleOwner);
+ if(!dryRun) {
+ query = "UPDATE authz.perm set roles = roles - "
+ + "{'" + nk.name + "|owner'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='*'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+
+ }
+
+
+
+ // Owner
+ rk = Role.keys.get(roleOwner);
+ if(rk==null) {
+ trans.warn().log(nk.name + " is missing role: " + roleOwner);
+ if(!dryRun) {
+ query = "INSERT INTO authz.role(ns, name, description, perms) VALUES('"
+ + nk.name
+ + "','owner','Automatic Owners',"
+ + "{'" + nk.name + "|access|*|read'});";
+ session.execute(query);
+ env.info().log(query);
+
+ }
+ } else {
+ // Role Owner should be linked to permRead
+ if(!rk.perms.contains(permRead)) {
+ trans.warn().log(roleOwner,"is not linked to",permRead);
+ if(!dryRun) {
+ query = "UPDATE authz.role set perms = perms + "
+ + "{'" + nk.name + "|access|*|read'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='owner'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ if(rk.perms.contains(permReadPrev)) {
+ query = "UPDATE authz.role set perms = perms - "
+ + "{'" + nk.name + ".access|*|read'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='owner'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ }
+ }
+ }
+ // Role Owner should not be linked to PermAll
+ if(rk.perms.contains(permAll)) {
+ trans.warn().log(roleAdmin,"should not be linked to",permAll);
+ if(!dryRun) {
+ query = "UPDATE authz.role set perms = perms - "
+ + "{'" + nk.name + "|access|*|*'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='admin'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+
+ }
+
+ pk = Perm.keys.get(permRead);
+ if(pk==null) {
+ trans.warn().log(nk.name + " is missing perm: " + permRead);
+ if(!dryRun) {
+ query = "INSERT INTO authz.perm(ns, type,instance,action,description, roles) VALUES ('"
+ + nk.name
+ + "','access','*','read','Namespace Read',"
+ + "{'" + nk.name + "|owner'});";
+ session.execute(query);
+ env.info().log(query);
+ }
+ } else {
+ // PermRead should be linked to roleOwner
+ if(!pk.roles.contains(roleOwner)) {
+ trans.warn().log(permRead, "is not linked to", roleOwner);
+ if(!dryRun) {
+ query = "UPDATE authz.perm set roles = roles + "
+ + "{'" + nk.name + "|owner'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='read'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ if(pk.roles.contains(roleOwnerPrev)) {
+ query = "UPDATE authz.perm set roles = roles - "
+ + "{'" + nk.name + ".owner'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='read'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+
+ }
+ }
+ }
+ // PermRead should be not linked to RoleAdmin
+ if(pk.roles.contains(roleAdmin)) {
+ if(dryRun) {
+ trans.warn().log(permRead,"should not be linked to",roleAdmin);
+ } else {
+ query = "UPDATE authz.perm set roles = roles - "
+ + "{'" + nk.name + "|admin'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='read'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+ }
+
+
+ int dot = nk.name.lastIndexOf('.');
+ String parent;
+ if(dot<0) {
+ parent = ".";
+ } else {
+ parent = nk.name.substring(0, dot);
+ }
+
+ if(!parent.equals(nk.parent)) {
+ if(dryRun) {
+ trans.warn().log(nk.name + " is missing namespace data");
+ } else {
+ query = "UPDATE authz.ns SET parent='"+parent+"'" +
+ " WHERE name='" + nk.name + "';";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+
+ // During Migration:
+ List<NsAttrib> swm = NsAttrib.byNS.get(nk.name);
+ boolean hasSwmV1 = false;
+ if(swm!=null) {for(NsAttrib na : swm) {
+ if("swm".equals(na.key) && "v1".equals(na.value)) {
+ hasSwmV1=true;
+ break;
+ }
+ }}
+ String roleMem = nk.name+"|member";
+ Role rm = Role.keys.get(roleMem); // Accommodate new role key
+ if(rm==null && hasSwmV1) {
+ query = "INSERT INTO authz.role(ns, name, description, perms) VALUES ('"
+ + nk.name
+ + "','member','Member',"
+ + "{'" + nk.name + "|access|*|read'});";
+ session.execute(query);
+ query = "UPDATE authz.role set perms = perms + "
+ + "{'" + nk.name + "|access|*|read'} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='member'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ if(rm!=null) {
+ if(!rm.perms.contains(permRead)) {
+ if(isDryRun()) {
+ env.info().log(nk.name+"|member needs " + nk.name + "|access|*|read");
+ } else {
+ query = "UPDATE authz.perm set roles = roles + "
+ + "{'" + nk.name + "|member'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='access' AND instance='*' and action='read'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ query = "UPDATE authz.role set perms = perms + "
+ + "{'" + nk.name + "|access|*|read'"
+ + (hasSwmV1?",'"+nk.name+"|swm.star|*|*'":"")
+ + "} "
+ + "WHERE ns='"+ nk.name + "' AND "
+ + "name='member'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ if(hasSwmV1) {
+ query = "UPDATE authz.perm set roles = roles + "
+ + "{'" + nk.name + "|member'} WHERE "
+ + "ns='"+ pk.ns + "' AND "
+ + "type='swm.star' AND instance='*' and action='*'"
+ + ";";
+ session.execute(query);
+ env.info().log(query);
+ }
+ }
+ }
+ }
+
+
+
+ // Best Guess Owner
+
+// owner = Role.keys.get(ns.)
+ }
+ } finally {
+ tt.done();
+ }
+
+ }
+
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java
new file mode 100644
index 0000000..2df123d
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckRolePerm.java
@@ -0,0 +1,164 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.Set;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Split;
+
+public class CheckRolePerm extends Batch{
+
+ public CheckRolePerm(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+ NS.load(trans,session,NS.v2_0_11);
+ Role.load(trans, session);
+ Perm.load(trans, session);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ // Run for Roles
+ trans.info().log("Checking for Role/Perm mis-match");
+
+ String query;
+ /// Evaluate from Role side
+ for(Role roleKey : Role.data.keySet()) {
+ for(String perm : Role.data.get(roleKey)) {
+ Perm pk = Perm.keys.get(perm);
+ if(pk==null) {
+ NS ns=null;
+ String msg = perm + " in role " + roleKey.fullName() + " does not exist";
+ String newPerm;
+ String[] s = Split.split('|', perm);
+ if(s.length==3) {
+ int i;
+ String find = s[0];
+ for(i=find.lastIndexOf('.');ns==null && i>=0;i=find.lastIndexOf('.', i-1)) {
+ ns = NS.data.get(find.substring(0,i));
+ }
+ if(ns==null) {
+ newPerm = perm;
+ } else {
+ newPerm = ns.name + '|' + s[0].substring(i+1) + '|' + s[1] + '|' + s[2];
+ }
+ } else {
+ newPerm = perm;
+ }
+ if(dryRun) {
+ if(ns==null) {
+ trans.warn().log(msg, "- would remove role from perm;");
+ } else {
+ trans.warn().log(msg, "- would update role in perm;");
+ }
+ } else {
+ if(ns!=null) {
+ query = "UPDATE authz.role SET perms = perms + {'" +
+ newPerm + "'}"
+ + (roleKey.description==null?", description='clean'":"")
+ + " WHERE "
+ + "ns='" + roleKey.ns
+ + "' AND name='" + roleKey.name + "';";
+ trans.warn().log("Fixing role in perm",query);
+ session.execute(query);
+ }
+
+ query = "UPDATE authz.role SET perms = perms - {'"
+ + perm.replace("'", "''") + "'}"
+ + (roleKey.description==null?", description='clean'":"")
+ + " WHERE "
+ + "ns='" + roleKey.ns
+ + "' AND name='" + roleKey.name + "';";
+ session.execute(query);
+ trans.warn().log(msg, "- removing role from perm");
+// env.info().log( "query: " + query );
+ }
+ } else {
+ Set<String> p_roles = Perm.data.get(pk);
+ if(p_roles!=null && !p_roles.contains(roleKey.encode())) {
+ String msg = perm + " does not have role: " + roleKey;
+ if(dryRun) {
+ trans.warn().log(msg,"- should add this role to this perm;");
+ } else {
+ query = "update authz.perm set roles = roles + {'"
+ + roleKey.encode() + "'}"
+ + (pk.description==null?", description=''":"")
+ + " WHERE "
+ + "ns='" + pk.ns
+ + "' AND type='" + pk.type
+ + "' AND instance='" + pk.instance
+ + "' AND action='" + pk.action
+ + "';";
+ session.execute(query);
+ trans.warn().log(msg,"- adding perm to role");
+ }
+
+ }
+ }
+ }
+ }
+
+ for(Perm permKey : Perm.data.keySet()) {
+ for(String role : Perm.data.get(permKey)) {
+ Role rk = Role.keys.get(role);
+ if(rk==null) {
+ String s = role + " in perm " + permKey.encode() + " does not exist";
+ if(dryRun) {
+ trans.warn().log(s,"- would remove perm from role;");
+ } else {
+ query = "update authz.perm set roles = roles - {'"
+ + role.replace("'","''") + "'}"
+ + (permKey.description==null?", description='clean'":"")
+ + " WHERE "
+ + "ns='" + permKey.ns
+ + "' AND type='" + permKey.type
+ + "' AND instance='" + permKey.instance
+ + "' AND action='" + permKey.action + "';";
+ session.execute(query);
+ trans.warn().log(s,"- removing role from perm");
+ }
+ } else {
+ Set<String> r_perms = Role.data.get(rk);
+ if(r_perms!=null && !r_perms.contains(permKey.encode())) {
+ String s ="Role '" + role + "' does not have perm: '" + permKey + '\'';
+ if(dryRun) {
+ trans.warn().log(s,"- should add this perm to this role;");
+ } else {
+ query = "update authz.role set perms = perms + {'"
+ + permKey.encode() + "'}"
+ + (rk.description==null?", description=''":"")
+ + " WHERE "
+ + "ns='" + rk.ns
+ + "' AND name='" + rk.name + "';";
+ session.execute(query);
+ trans.warn().log(s,"- adding role to perm");
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java
new file mode 100644
index 0000000..5064140
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/CheckUR.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.NS.NSSplit;
+import com.att.authz.helpers.UserRole;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class CheckUR extends Batch{
+
+ public CheckUR(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+ NS.load(trans, session,NS.v2_0_11);
+ UserRole.load(trans, session,UserRole.v2_0_11);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ trans.info().log("Get All Namespaces");
+
+
+ String query;
+
+ /// Evaluate
+ for(UserRole urKey : UserRole.data) {
+ NSSplit nss = NS.deriveParent(urKey.role);
+ if(nss==null && NS.data.size()>0 ) { // there is no Namespace for this UserRole
+ if(dryRun) {
+ trans.warn().printf("Would delete %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+ } else {
+ query = "DELETE FROM authz.user_role WHERE "
+ + "user='" + urKey.user
+ + "' AND role='" + urKey.role
+ + "';";
+ session.execute(query);
+ trans.warn().printf("Deleting %s %s, which has no corresponding Namespace",urKey.user,urKey.role);
+ }
+ } else if(urKey.ns == null || urKey.rname == null || !urKey.role.equals(urKey.ns+'.'+urKey.rname)) {
+ if(dryRun) {
+ trans.warn().log(urKey,"needs to be split and added to Record (", urKey.ns, urKey.rname,")");
+ } else {
+ query = "UPDATE authz.user_role SET ns='" + nss.ns
+ + "', rname='" + nss.other
+ + "' WHERE "
+ + "user='" + urKey.user
+ + "' AND role='" + urKey.role
+ + "';";
+ session.execute(query);
+ trans.warn().log("Setting ns and rname",query);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ }
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/Expiring.java b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java
new file mode 100644
index 0000000..79f3759
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/Expiring.java
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.actions.Action;
+import com.att.authz.actions.ActionDAO;
+import com.att.authz.actions.CredDelete;
+import com.att.authz.actions.CredPrint;
+import com.att.authz.actions.FADelete;
+import com.att.authz.actions.FAPrint;
+import com.att.authz.actions.Key;
+import com.att.authz.actions.URDelete;
+import com.att.authz.actions.URFutureApprove;
+import com.att.authz.actions.URFuturePrint;
+import com.att.authz.actions.URPrint;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.Cred.Instance;
+import com.att.authz.helpers.Future;
+import com.att.authz.helpers.Notification;
+import com.att.authz.helpers.UserRole;
+import com.att.authz.layer.Result;
+import com.att.authz.org.Organization.Identity;
+import com.att.dao.aaf.cass.CredDAO;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class Expiring extends Batch {
+
+ private final Action<UserRole,Void> urDelete,urPrint;
+ private final Action<UserRole,List<Identity>> urFutureApprove;
+ private final Action<CredDAO.Data,Void> crDelete,crPrint;
+ private final Action<Future,Void> faDelete;
+// private final Email email;
+ private final Key<UserRole> memoKey;
+
+ public Expiring(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ trans.info().log("Starting Connection Process");
+ TimeTaken tt0 = trans.start("Cassandra Initialization", Env.SUB);
+ try {
+ urPrint = new URPrint("Expired:");
+ crPrint = new CredPrint("Expired:");
+
+ URFutureApprove ufr = new URFutureApprove(trans,cluster);
+ memoKey = ufr;
+
+ if(isDryRun()) {
+ urDelete = new URPrint("Would Delete:");
+ // While Testing
+// urFutureApprove = ufr;
+ urFutureApprove = new URFuturePrint("Would setup Future/Approvals");
+ crDelete = new CredPrint("Would Delete:");
+ faDelete = new FAPrint("Would Delete:");
+// email = new EmailPrint();
+
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+
+ } else {
+ TimeTaken tt = trans.start("Connect to Cluster with DAOs", Env.REMOTE);
+ try {
+ ActionDAO<UserRole,Void> adao;
+ urDelete = adao = new URDelete(trans, cluster);
+ urFutureApprove = new URFutureApprove(trans,adao);
+ faDelete = new FADelete(trans, adao);
+
+ crDelete = new CredDelete(trans, adao);
+// email = new Email();
+ TimeTaken tt2 = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = adao.getSession(trans);
+ } finally {
+ tt2.done();
+ }
+ } finally {
+ tt.done();
+ }
+ }
+
+ UserRole.load(trans, session, UserRole.v2_0_11);
+ Cred.load(trans, session);
+ Notification.load(trans, session, Notification.v2_0_14);
+ Future.load(trans,session,Future.v2_0_15);
+ } finally {
+ tt0.done();
+ }
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ // Setup Date boundaries
+ Date now = new Date();
+ GregorianCalendar gc = new GregorianCalendar();
+ gc.setTime(now);
+ gc.add(GregorianCalendar.MONTH, 1);
+ Date future = gc.getTime();
+ gc.setTime(now);
+ gc.add(GregorianCalendar.MONTH, -1);
+ Date tooLate = gc.getTime();
+ int count = 0, deleted=0;
+
+// List<Notification> ln = new ArrayList<Notification>();
+ TimeTaken tt;
+
+ // Run for Expired Futures
+ trans.info().log("Checking for Expired Futures");
+ tt = trans.start("Delete old Futures", Env.REMOTE);
+ try {
+ List<Future> delf = new ArrayList<Future>();
+ for(Future f : Future.data) {
+ AuthzTrans localTrans = env.newTransNoAvg();
+ if(f.expires.before(now)) {
+ faDelete.exec(localTrans, f);
+ delf.add(f);
+ }
+ }
+ Future.delete(delf);
+ } finally {
+ tt.done();
+ }
+
+ // Run for Roles
+ trans.info().log("Checking for Expired Roles");
+ try {
+ for(UserRole ur : UserRole.data) {
+ AuthzTrans localTrans = env.newTransNoAvg();
+ if(ur.expires.before(tooLate)) {
+ if("owner".equals(ur.rname)) { // don't delete Owners, even if Expired
+ urPrint.exec(localTrans,ur);
+ } else {
+ urDelete.exec(localTrans,ur);
+ ++deleted;
+ trans.logAuditTrail(trans.info());
+ }
+ ++count;
+ } else if(ur.expires.before(future)) {
+ List<Future> fbm = Future.byMemo.get(memoKey.key(ur));
+ if(fbm==null || fbm.isEmpty()) {
+ Result<List<Identity>> rapprovers = urFutureApprove.exec(localTrans, ur);
+ if(rapprovers.isOK()) {
+ for(Identity ou : rapprovers.value) {
+// Notification n = Notification.addApproval(localTrans,ou);
+// if(n.org==null) {
+// n.org = getOrgFromID(localTrans, ur.user);
+// }
+// ln.add(n);
+ urPrint.exec(localTrans,ur);
+ if(isDryRun()) {
+ trans.logAuditTrail(trans.info());
+ }
+ }
+ }
+ }
+ ++count;
+ }
+ }
+ } finally {
+ env.info().log("Found",count,"roles expiring before",future);
+ env.info().log("deleting",deleted,"roles expiring before",tooLate);
+ }
+
+// // Email Approval Notification
+// email.subject("AAF Role Expiration Warning (ENV: %s)", batchEnv);
+// email.indent("");
+// for(Notification n: ln) {
+// if(n.org==null) {
+// trans.error().log("No Organization for Notification");
+// } else if(n.update(trans, session, isDryRun())) {
+// email.clear();
+// email.addTo(n.user);
+// email.line(n.text(new StringBuilder()).toString());
+// email.exec(trans,n.org);
+// }
+// }
+ // 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()) {
+ AuthzTrans localTrans = env.newTransNoAvg();
+ 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(localTrans, crd);
+ } else if(last==null || inst.expires.after(last)) {
+ last = inst.expires;
+ }
+ }
+ if(last!=null) {
+ if(last.before(future)) {
+ crd.expires = last;
+ crPrint.exec(localTrans, crd);
+ ++count;
+ }
+ }
+ }
+ }
+ } finally {
+ env.info().log("Found",count,"current creds expiring before",future);
+ }
+
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ for(Action<?,?> action : new Action<?,?>[] {urDelete,crDelete}) {
+ if(action instanceof ActionDAO) {
+ ((ActionDAO<?,?>)action).close(trans);
+ }
+ }
+ session.close();
+ }
+
+}
diff --git a/authz-batch/src/main/java/com/att/authz/reports/NSDump.java b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java
new file mode 100644
index 0000000..a15fc24
--- /dev/null
+++ b/authz-batch/src/main/java/com/att/authz/reports/NSDump.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.reports;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.Date;
+import java.util.List;
+
+import com.att.authz.Batch;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.helpers.Cred;
+import com.att.authz.helpers.NS;
+import com.att.authz.helpers.Perm;
+import com.att.authz.helpers.Role;
+import com.att.authz.helpers.UserRole;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+public class NSDump extends Batch{
+ private PrintStream out = System.out;
+ private final String ns, admin, owner;
+
+ public NSDump(AuthzTrans trans) throws APIException, IOException {
+ super(trans.env());
+ if(args().length>0) {
+ ns = args()[0];
+ } else {
+ throw new APIException("NSDump requires \"NS\" parameter");
+ }
+ admin = ns + "|admin";
+ owner = ns + "|owner";
+
+ TimeTaken tt = trans.start("Connect to Cluster", Env.REMOTE);
+ try {
+ session = cluster.connect();
+ } finally {
+ tt.done();
+ }
+
+ NS.loadOne(trans, session,NS.v2_0_11,ns);
+ Role.loadOneNS(trans, session, ns);
+ if(Role.data.keySet().size()>5) {
+ UserRole.load(trans, session,UserRole.v2_0_11);
+ } else {
+ for(Role r : Role.data.keySet()) {
+ UserRole.loadOneRole(trans, session, UserRole.v2_0_11, r.fullName());
+ }
+ }
+ Perm.loadOneNS(trans,session,ns);
+ Cred.loadOneNS(trans, session, ns);
+ }
+
+ @Override
+ protected void run(AuthzTrans trans) {
+ Date now = new Date();
+ for(NS ns : NS.data.values()) {
+ out.format("# Data for Namespace [%s] - %s\n",ns.name,ns.description);
+ out.format("ns create %s",ns);
+ boolean first = true;
+ List<UserRole> owners = UserRole.byRole.get(owner);
+ if(owners!=null)for(UserRole ur : owners) {
+ if(first) {
+ out.append(' ');
+ first = false;
+ } else {
+ out.append(',');
+ }
+ out.append(ur.user);
+ }
+ first = true;
+ List<UserRole> admins = UserRole.byRole.get(admin);
+ if(admins!=null)for(UserRole ur : admins) {
+ if(first) {
+ out.append(' ');
+ first = false;
+ } else {
+ out.append(',');
+ }
+ out.append(ur.user);
+ }
+ out.println();
+
+ // Load Creds
+ Date last;
+ for(Cred c : Cred.data.values()) {
+ for(int i : c.types()) {
+ last = c.last(i);
+ if(last!=null && now.before(last)) {
+ switch(i) {
+ case 1:
+ out.format(" user cred add %s %s\n", c.id,"new2you!");
+ break;
+ case 200:
+ out.format(" # CERT needs registering for %s\n", c.id);
+ break;
+ default:
+ out.format(" # Unknown Type for %s\n", c.id);
+ }
+ }
+ }
+ }
+
+ // Load Roles
+ for(Role r : Role.data.keySet()) {
+ if(!"admin".equals(r.name) && !"owner".equals(r.name)) {
+ out.format(" role create %s\n",r.fullName());
+ List<UserRole> lur = UserRole.byRole.get(r.fullName());
+ if(lur!=null)for(UserRole ur : lur) {
+ if(ur.expires.after(now)) {
+ out.format(" request role user add %s %s\n", ur.role,ur.user);
+ }
+ }
+ }
+ }
+
+ // Load Perms
+ for(Perm r : Perm.data.keySet()) {
+ out.format(" perm create %s.%s %s %s\n",r.ns,r.type,r.instance,r.action);
+ for(String role : r.roles) {
+ out.format(" request perm grant %s.%s %s %s %s\n", r.ns,r.type,r.instance,r.action,Role.fullName(role));
+ }
+ }
+
+ }
+ }
+
+ @Override
+ protected void _close(AuthzTrans trans) {
+ session.close();
+ aspr.info("End " + this.getClass().getSimpleName() + " processing" );
+ }
+
+}
diff --git a/authz-batch/src/main/scripts/SyncV1V2 b/authz-batch/src/main/scripts/SyncV1V2
new file mode 100644
index 0000000..c3a9115
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV1V2
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="SyncV1V2"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
diff --git a/authz-batch/src/main/scripts/SyncV1V2daily b/authz-batch/src/main/scripts/SyncV1V2daily
new file mode 100644
index 0000000..5c89d04
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV1V2daily
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="SyncV1V2 v1 v2"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
diff --git a/authz-batch/src/main/scripts/SyncV2V1 b/authz-batch/src/main/scripts/SyncV2V1
new file mode 100644
index 0000000..e766218
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV2V1
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="SyncV2V1"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
\ No newline at end of file
diff --git a/authz-batch/src/main/scripts/SyncV2V1daily b/authz-batch/src/main/scripts/SyncV2V1daily
new file mode 100644
index 0000000..8a67692
--- /dev/null
+++ b/authz-batch/src/main/scripts/SyncV2V1daily
@@ -0,0 +1,17 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+
+cd $ROOT_DIR
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="SyncV2V1 v2 v1"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
\ No newline at end of file
diff --git a/authz-batch/src/main/scripts/V1daily b/authz-batch/src/main/scripts/V1daily
new file mode 100644
index 0000000..9f6c4ca
--- /dev/null
+++ b/authz-batch/src/main/scripts/V1daily
@@ -0,0 +1,46 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+ENV_CONTEXT=_ENV_CONTEXT_
+
+cd $ROOT_DIR
+
+if [ ! -e "$ROOT_DIR/data/stage" ]; then
+ mkdir -p $ROOT_DIR/data/stage
+fi
+
+if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then
+ mkdir -p $ROOT_DIR/data/$ENV_CONTEXT
+ ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage
+fi
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="V1DataFile all"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+
+cd $ROOT_DIR/data/stage
+LATEST=`ls -tr v1*.dat | tail -1`
+if [ "$LATEST" != "" ]; then
+ > ../v1.lock
+ cp -p $LATEST ../v1.dat
+ rm ../v1.lock
+fi
+
+LATEST=`ls -tr v1*.skip | tail -1`
+if [ "$LATEST" != "" ]; then
+ cp -p $LATEST ../v1.skip
+fi
+
+for FILE in `ls v1* | grep -v .gz`; do
+ gzip $FILE
+done
+
+
diff --git a/authz-batch/src/main/scripts/V2daily b/authz-batch/src/main/scripts/V2daily
new file mode 100644
index 0000000..c547a94
--- /dev/null
+++ b/authz-batch/src/main/scripts/V2daily
@@ -0,0 +1,46 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+ENV_CONTEXT=_ENV_CONTEXT_
+
+cd $ROOT_DIR
+
+if [ ! -e "$ROOT_DIR/data/stage" ]; then
+ mkdir -p $ROOT_DIR/data/stage
+fi
+
+if [ ! -e "$ROOT_DIR/data/$ENV_CONTEXT/stage" ]; then
+ mkdir -p $ROOT_DIR/data/$ENV_CONTEXT
+ ln -s $ROOT_DIR/data/stage $ROOT_DIR/data/$ENV_CONTEXT/stage
+fi
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+CMD="V2DataFile all"
+echo $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP com.att.authz.Batch $CMD >> $ROOT_DIR/cronlog
+date >> $ROOT_DIR/cronlog
+
+cd $ROOT_DIR/data/stage
+LATEST=`ls -tr v2*.dat | tail -1`
+if [ "$LATEST" != "" ]; then
+ > ../v2.lock
+ cp -p $LATEST ../v2.dat
+ rm ../v2.lock
+fi
+
+LATEST=`ls -tr v2*.skip | tail -1`
+if [ "$LATEST" != "" ]; then
+ cp -p $LATEST ../v2.skip
+fi
+
+for FILE in `ls v2* | grep -v .gz`; do
+ gzip $FILE
+done
+
+
diff --git a/authz-batch/src/main/scripts/aafbch b/authz-batch/src/main/scripts/aafbch
new file mode 100644
index 0000000..fdeb22e
--- /dev/null
+++ b/authz-batch/src/main/scripts/aafbch
@@ -0,0 +1,21 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+PATH=${PATH}:${JAVA_HOME}/bin
+ROOT_DIR=_ROOT_DIR_
+cd $ROOT_DIR
+
+if [ "$1" = "InnerConsistency" ]; then
+ CLS=com.att.authz.temp.InnerConsistency
+ shift
+else
+ CLS=com.att.authz.Batch
+fi
+
+CP=${ROOT_DIR}/etc
+for FILE in `ls $ROOT_DIR/lib/*.jar`; do
+ CP=$CP:$FILE
+done
+
+date
+$JAVA_HOME/bin/java -Xmx2048m -classpath $CP $CLS $*
+date
diff --git a/authz-batch/src/main/scripts/run_batch b/authz-batch/src/main/scripts/run_batch
new file mode 100644
index 0000000..c09ea0a
--- /dev/null
+++ b/authz-batch/src/main/scripts/run_batch
@@ -0,0 +1,16 @@
+#!/bin/env bash
+
+if [[ $# < 1 ]]; then
+ echo "USAGE: run_batch ExpiryNotification|ApprNotify|JobChange|RoleExpiration|ValidateUsers"
+ exit 1;
+fi
+
+JAVA_HOME=_JAVA_HOME_
+AAF_CP="_ROOT_DIR_/etc"
+for JAR in `find _ROOT_DIR_/lib -name *.jar` ; do
+ AAF_CP="$AAF_CP:$JAR"
+done
+
+$JAVA_HOME/bin/java -cp $AAF_CP com.att.authz.Batch $*
+
+