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 $*
+
+
diff --git a/authz-cass/pom.xml b/authz-cass/pom.xml
new file mode 100644
index 0000000..f1e34a7
--- /dev/null
+++ b/authz-cass/pom.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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/xsd/maven-4.0.0.xsd">

+	<modelVersion>4.0.0</modelVersion>

+	<parent>

+		<groupId>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-cass</artifactId>

+	<name>Authz Cass</name>

+	<description>Cassandra DAOs 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>

+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

+		<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+	</properties>

+	<dependencies>

+		<dependency>

+			<groupId>org.onap.aaf.authz</groupId>

+			<artifactId>authz-core</artifactId>

+		</dependency>

+

+		<dependency>

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+		</dependency>

+

+       	<dependency>

+			<groupId>com.datastax.cassandra</groupId>

+			<artifactId>cassandra-driver-core</artifactId>

+		</dependency>	

+		

+		<!-- Cassandra prefers Snappy and LZ4 libs for performance -->

+		<dependency>

+		  <groupId>org.xerial.snappy</groupId>

+		  <artifactId>snappy-java</artifactId>

+		  <version>1.1.1-M1</version>

+		</dependency>

+		

+		<dependency>

+		  <groupId>net.jpountz.lz4</groupId>

+		  <artifactId>lz4</artifactId>

+		  <version>1.2.0</version>

+		</dependency>

+		

+		<dependency>

+          <groupId>com.googlecode.jcsv</groupId>

+          <artifactId>jcsv</artifactId>

+          <version>1.4.0</version>

+		</dependency>

+		

+		<dependency>

+			<groupId>org.slf4j</groupId>

+			<artifactId>slf4j-log4j12</artifactId>

+	        <scope>test</scope>

+		</dependency>

+		

+	

+	</dependencies>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-jarsigner-plugin</artifactId>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-deploy-plugin</artifactId>

+		    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

+	<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>	

+</project>

+

diff --git a/authz-cass/src/main/cql/ecomp.cql b/authz-cass/src/main/cql/ecomp.cql
new file mode 100644
index 0000000..967d6da
--- /dev/null
+++ b/authz-cass/src/main/cql/ecomp.cql
@@ -0,0 +1,118 @@
+//
+//  Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+// 
+USE authz;
+
+// Create Root pass
+INSERT INTO cred (id,ns,type,cred,expires)
+  VALUES ('dgl@openecomp.org','org.openecomp',1,0xab3831f27b39d7a039f9a92aa2bbfe51,'2020-12-31');
+
+// Create 'com' root NS
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com',1,'Root Namespace',null,1);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com','admin',{'com.access|*|*'},'Com Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com','owner',{'com.access|*|read'},'Com Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com','access','*','read',{'com.owner'},'Com Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com','access','*','*',{'com.admin'},'Com Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.owner','2020-12-31','com','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.admin','2020-12-31','com','admin');
+
+// Create org root NS
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org',1,'Root Namespace Org',null,1);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org','admin',{'org.access|*|*'},'Com Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org','owner',{'org.access|*|read'},'Com Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org','access','*','read',{'org.owner'},'Com Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org','access','*','*',{'org.admin'},'Com Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.owner','2020-12-31','org','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.admin','2020-12-31','org','admin');
+
+
+// Create com.att
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com.att',2,'AT&T Namespace','com',2);
+
+INSERT INTO role(ns, name, perms,description)
+  VALUES('com.att','admin',{'com.att.access|*|*'},'AT&T Admins');
+
+INSERT INTO role(ns, name, perms,description)
+  VALUES('com.att','owner',{'com.att.access|*|read'},'AT&T Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles,description) 
+  VALUES ('com.att','access','*','read',{'com.att.owner'},'AT&T Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles,description) 
+  VALUES ('com.att','access','*','*',{'com.att.admin'},'AT&T Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.owner','2020-12-31','com.att','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.admin','2020-12-31','com.att','admin');
+
+// Create com.att.aaf
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com.att.aaf',3,'Application Authorization Framework','com.att',3);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com.att.aaf','admin',{'com.att.aaf.access|*|*'},'AAF Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com.att.aaf','owner',{'com.att.aaf.access|*|read'},'AAF Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com.att.aaf','access','*','read',{'com.att.aaf.owner'},'AAF Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com.att.aaf','access','*','*',{'com.att.aaf.admin'},'AAF Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.aaf.admin','2020-12-31','com.att.aaf','admin');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.aaf.owner','2020-12-31','com.att.aaf','owner');
+  
+
+// Create org.openecomp
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org.openecomp',2,'Open EComp NS','com.att',2);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org.openecomp','admin',{'org.openecomp.access|*|*'},'OpenEcomp Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org.openecomp','owner',{'org.openecomp.access|*|read'},'OpenEcomp Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp','access','*','read',{'org.openecomp.owner'},'OpenEcomp Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp','access','*','*',{'org.openecomp.admin'},'OpenEcomp Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.openecomp.admin','2020-12-31','org.openecomp','admin');
diff --git a/authz-cass/src/main/cql/init.cql b/authz-cass/src/main/cql/init.cql
new file mode 100644
index 0000000..3b2688a
--- /dev/null
+++ b/authz-cass/src/main/cql/init.cql
@@ -0,0 +1,212 @@
+//
+//  Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+//
+// For Developer Machine single instance
+//
+ CREATE KEYSPACE authz
+ WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor':1};
+ 
+USE authz;
+
+//
+// CORE Table function
+//
+
+// Namespace - establish hierarchical authority to modify
+// Permissions and Roles
+// "scope" is flag to determine Policy.  Typical important scope
+// is "company" (1)
+CREATE TABLE ns (
+  name			varchar,
+  scope			int,  // deprecated 2.0.11
+  description   	varchar,
+  parent 		varchar,
+  type			int,
+  PRIMARY KEY (name)  
+);
+CREATE INDEX ns_parent on ns(parent);
+  
+
+CREATE TABLE ns_attrib (
+  ns            varchar,
+  key           varchar,
+  value         varchar,
+  PRIMARY KEY (ns,key)
+);
+create index ns_attrib_key on ns_attrib(key);
+
+// Will be cached
+CREATE TABLE role (
+  ns	    varchar,
+  name		varchar,
+  perms		set<varchar>, // Use "Key" of "name|type|action"
+  description varchar,
+  PRIMARY KEY (ns,name)
+);
+CREATE INDEX role_name  ON role(name);
+ 
+// Will be cached
+CREATE TABLE perm (
+  ns	    varchar,
+  type 		varchar,
+  instance	varchar,
+  action	varchar,
+  roles		set<varchar>, // Need to find Roles given Permissions
+  description varchar,
+  PRIMARY KEY (ns,type,instance,action)
+);
+
+// This table is user for Authorization
+CREATE TABLE user_role (
+    user		varchar,
+    role		varchar, // deprecated: change to ns/rname after 2.0.11
+    ns			varchar,
+    rname		varchar,
+    expires		timestamp,
+    PRIMARY KEY(user,role)
+  );
+CREATE INDEX user_role_ns ON user_role(ns);
+CREATE INDEX user_role_role ON user_role(role);
+
+// This table is only for the case where return User Credential (MechID) Authentication
+CREATE TABLE cred (
+    id    varchar,
+    type  int,
+    expires timestamp,  
+    ns    varchar,
+    other int,
+    notes varchar,
+    cred  blob,
+    prev  blob,
+    PRIMARY KEY (id,type,expires)
+  );
+CREATE INDEX cred_ns ON cred(ns);
+
+// Certificate Cross Table
+//   coordinated with CRED type 2
+CREATE TABLE cert (
+    fingerprint blob,
+    id    	varchar,
+    x500	varchar,
+    expires 	timestamp,  
+    PRIMARY KEY (fingerprint)
+  );
+CREATE INDEX cert_id ON cert(id);
+CREATE INDEX cert_x500 ON cert(x500);
+
+CREATE TABLE notify (
+  user text,
+  type int,
+  last timestamp,
+  checksum int,
+  PRIMARY KEY (user,type)
+);
+
+CREATE TABLE x509 (
+  ca     text,
+  serial blob,
+  id     text,
+  x500   text,
+  x509   text,
+  PRIMARY KEY (ca,serial)
+);
+
+
+CREATE INDEX x509_id   ON x509 (id);
+CREATE INDEX x509_x500 ON x509 (x500);
+
+// 
+// Deployment Artifact (for Certman)
+//
+CREATE TABLE artifact (
+  mechid        text,
+  machine       text,
+  type          Set<text>,
+  sponsor       text,
+  ca            text,
+  dir           text,
+  appName       text,
+  os_user       text,
+  notify        text,
+  expires	timestamp,
+  renewDays   int,
+  PRIMARY KEY (mechid,machine)
+);
+CREATE INDEX artifact_machine ON artifact(machine); 
+
+//
+// Non-Critical Table functions
+//
+// Table Info - for Caching
+CREATE TABLE cache (
+   name		varchar,
+   seg		int, 		// cache Segment
+   touched	timestamp,
+   PRIMARY KEY(name,seg)
+);
+
+CREATE TABLE history (
+  id			timeuuid,
+  yr_mon		int,
+  user			varchar,
+  action 		varchar,
+  target		varchar,   // user, user_role, 
+  subject		varchar,   // field for searching main portion of target key
+  memo			varchar,   //description of the action
+  reconstruct 	blob,      //serialized form of the target
+  // detail 	Map<varchar, varchar>,  // additional information
+  PRIMARY KEY (id)
+);
+CREATE INDEX history_yr_mon ON history(yr_mon);
+CREATE INDEX history_user ON history(user); 
+CREATE INDEX history_subject ON history(subject); 
+
+// 
+// A place to hold objects to be created at a future time.
+//
+CREATE TABLE future (
+  id        uuid,  		// uniquify
+  target    varchar,   		// Target Table
+  memo	    varchar,    	// Description
+  start     timestamp, 		// When it should take effect
+  expires   timestamp, 		// When not longer valid
+  construct blob, 		// How to construct this object (like History)
+  PRIMARY KEY(id)
+);
+CREATE INDEX future_idx ON future(target);
+CREATE INDEX future_start_idx ON future(start);
+
+
+CREATE TABLE approval (
+  id	    timeuuid,	      // unique Key
+  ticket    uuid,	      // Link to Future Record
+  user 	    varchar,          // the user who needs to be approved
+  approver  varchar, 	      // user approving
+  type      varchar,          // approver types i.e. Supervisor, Owner
+  status    varchar,          // approval status. pending, approved, denied
+  memo      varchar,          // Text for Approval to know what's going on
+  operation varchar,	      // List operation to perform
+  PRIMARY KEY(id)
+ );
+CREATE INDEX appr_approver_idx ON approval(approver);
+CREATE INDEX appr_user_idx ON approval(user);
+CREATE INDEX appr_ticket_idx ON approval(ticket);
+CREATE INDEX appr_status_idx ON approval(status);
+
+CREATE TABLE delegate (
+  user      varchar,
+  delegate  varchar,
+  expires   timestamp,
+  PRIMARY KEY (user)  
+);
+CREATE INDEX delg_delg_idx ON delegate(delegate);
+
+//
+// Used by authz-batch processes to ensure only 1 runs at a time
+//
+CREATE TABLE run_lock (
+  class text,
+  host text,
+  start timestamp,
+  PRIMARY KEY ((class))
+);
diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/AbsCassDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/AbsCassDAO.java
new file mode 100644
index 0000000..c76a88f
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/AbsCassDAO.java
@@ -0,0 +1,497 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Deque;

+import java.util.List;

+import java.util.concurrent.ConcurrentLinkedDeque;

+

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.TransStore;

+import com.datastax.driver.core.BoundStatement;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ConsistencyLevel;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.ResultSetFuture;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.Session;

+import com.datastax.driver.core.exceptions.DriverException;

+

+public abstract class AbsCassDAO<TRANS extends TransStore,DATA> {

+	protected static final char DOT = '.';

+	protected static final char DOT_PLUS_ONE = '.'+1;

+	protected static final String FIRST_CHAR = Character.toString((char)0);

+	protected static final String LAST_CHAR = Character.toString((char)Character.MAX_VALUE);

+	protected static final int FIELD_COMMAS = 0;

+	protected static final int QUESTION_COMMAS = 1;

+	protected static final int ASSIGNMENT_COMMAS = 2;

+	protected static final int WHERE_ANDS = 3;

+	

+	private Cluster cluster; 

+	private Session session;

+	private final String keyspace;

+	// If this is null, then we own session

+	private final AbsCassDAO<TRANS,?> owningDAO;

+	protected Class<DATA> dataClass;

+	private final String name;

+	private static Slot sessionSlot;

+	//private static final ArrayList<AbsCassDAO<? extends TransStore,?>.PSInfo> psinfos = new ArrayList<AbsCassDAO<TransStore,?>.PSInfo>();

+	private static final ArrayList<AbsCassDAO<? extends TransStore,?>.PSInfo> psinfos = new ArrayList<AbsCassDAO<? extends TransStore,?>.PSInfo>();

+	private static final List<Object> EMPTY = new ArrayList<Object>(0);

+	private static final Deque<ResetRequest> resetDeque = new ConcurrentLinkedDeque<ResetRequest>();

+	private static boolean resetTrigger = false;

+	private static long nextAvailableReset = 0;

+	

+

+	public AbsCassDAO(TRANS trans, String name, Cluster cluster, String keyspace, Class<DATA> dataClass) {

+		this.name = name;

+		this.cluster = cluster;

+		this.keyspace = keyspace;

+		owningDAO = null;  // we own session

+		session = null;

+		this.dataClass = dataClass;

+		

+	}

+

+	public AbsCassDAO(TRANS trans, String name, AbsCassDAO<TRANS,?> aDao, Class<DATA> dataClass) {      

+		this.name = name;

+		cluster = aDao.cluster;

+		keyspace = aDao.keyspace;

+		session = null;

+		owningDAO = aDao; // We do not own session

+		this.dataClass = dataClass;

+	}

+	

+	public static void setSessionSlot(Slot slot) {

+		sessionSlot = slot;

+	}

+

+	//Note: Lower case ON PURPOSE. These names used to create History Messages

+	public enum CRUD {

+		create,read,update,delete

+	;

+

+}

+

+	public class PSInfo {

+		private BoundStatement ps;

+		private final int size;

+		private final Loader<DATA> loader;

+		private final CRUD crud; // Store CRUD, because it makes a difference in Object Order, see Loader

+		private final String cql;

+		private final ConsistencyLevel consistency;

+

+

+		/**

+		 * Create a PSInfo and create Prepared Statement

+		 * 

+		 * @param trans

+		 * @param theCQL

+		 * @param loader

+		 */

+		public PSInfo(TRANS trans, String theCQL, Loader<DATA> loader, ConsistencyLevel consistency) {

+			this.loader = loader;

+			this.consistency=consistency;

+			psinfos.add(this);

+

+			cql = theCQL.trim().toUpperCase();

+			if(cql.startsWith("INSERT")) {

+				crud = CRUD.create;

+			} else if(cql.startsWith("UPDATE")) {

+				crud = CRUD.update;

+			} else if(cql.startsWith("DELETE")) {

+				crud = CRUD.delete;

+			} else {

+				crud = CRUD.read;

+			}

+			

+			int idx = 0, count=0;

+			while((idx=cql.indexOf('?',idx))>=0) {

+				++idx;

+				++count;

+			}

+			size=count;

+		}

+		

+		public synchronized void reset() {

+			ps = null;

+		}

+		

+		private BoundStatement ps(TransStore trans) throws APIException, IOException {

+			if(ps==null) {

+				synchronized(this) {

+					if(ps==null) {

+						TimeTaken tt = trans.start("Preparing PSInfo " + crud.toString().toUpperCase() + " on " + name,Env.SUB);

+						try {

+							ps = new BoundStatement(getSession(trans).prepare(cql));

+							ps.setConsistencyLevel(consistency);

+						} catch (DriverException e) {

+							reportPerhapsReset(trans,e);

+							throw e;

+						} finally {

+							tt.done();

+						}

+					}

+				}

+			}

+			return ps;

+		}

+

+		/**

+		 * Execute a Prepared Statement by extracting from DATA object

+		 * 

+		 * @param trans

+		 * @param text

+		 * @param data

+		 * @return

+		 */

+		public Result<ResultSetFuture> execAsync(TRANS trans, String text, DATA data) {

+			TimeTaken tt = trans.start(text, Env.REMOTE);

+			try {

+				return Result.ok(getSession(trans).executeAsync(

+						ps(trans).bind(loader.extract(data, size, crud))));

+			} catch (DriverException | APIException | IOException e) {

+				AbsCassDAO.this.reportPerhapsReset(trans,e);

+				return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);

+			} finally {

+				tt.done();

+			}

+		}

+

+		/**

+		 * Execute a Prepared Statement on Object[] key

+		 * 

+		 * @param trans

+		 * @param text

+		 * @param objs

+		 * @return

+		 */

+		public Result<ResultSetFuture> execAsync(TRANS trans, String text, Object ... objs) {

+			TimeTaken tt = trans.start(text, Env.REMOTE);

+			try {

+				return Result.ok(getSession(trans).executeAsync(ps(trans).bind(objs)));

+			} catch (DriverException | APIException | IOException e) {

+				AbsCassDAO.this.reportPerhapsReset(trans,e);

+				return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);

+			} finally {

+				tt.done();

+			}

+		}

+		

+		/* 

+		 * Note:

+		 * 

+		 */

+

+		/**

+		 * Execute a Prepared Statement by extracting from DATA object

+		 * 

+		 * @param trans

+		 * @param text

+		 * @param data

+		 * @return

+		 */

+		public Result<ResultSet> exec(TRANS trans, String text, DATA data) {

+			TimeTaken tt = trans.start(text, Env.REMOTE);

+			try {

+				/*

+				 * "execute" (and executeAsync)

+				 * Executes the provided query.

+					This method blocks until at least some result has been received from the database. However, 

+					for SELECT queries, it does not guarantee that the result has been received in full. But it 

+					does guarantee that some response has been received from the database, and in particular 

+					guarantee that if the request is invalid, an exception will be thrown by this method.

+

+					Parameters:

+					statement - the CQL query to execute (that can be any Statement).

+					Returns:

+						the result of the query. That result will never be null but can be empty (and will 

+						be for any non SELECT query).

+				 */

+				return Result.ok(getSession(trans).execute(

+						ps(trans).bind(loader.extract(data, size, crud))));

+			} catch (DriverException | APIException | IOException e) {

+				AbsCassDAO.this.reportPerhapsReset(trans,e);

+				return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);

+			} finally {

+				tt.done();

+			}

+		}

+

+		/**

+		 * Execute a Prepared Statement on Object[] key

+		 * 

+		 * @param trans

+		 * @param text

+		 * @param objs

+		 * @return

+		 */

+		public Result<ResultSet> exec(TRANS trans, String text, Object ... objs) {

+			TimeTaken tt = trans.start(text, Env.REMOTE);

+			try {

+				return Result.ok(getSession(trans).execute(ps(trans).bind(objs)));

+			} catch (DriverException | APIException | IOException e) {

+				AbsCassDAO.this.reportPerhapsReset(trans,e);

+				return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);

+			} finally {

+				tt.done();

+			}

+		}

+

+		/**

+		 * Read the Data from Cassandra given a Prepared Statement (defined by the

+		 * DAO Instance)

+		 *

+		 * This is common behavior among all DAOs.

+		 * @throws DAOException

+		 */

+		public Result<List<DATA>> read(TRANS trans, String text, Object[] key) {

+			TimeTaken tt = trans.start(text,Env.REMOTE);

+			

+			ResultSet rs;

+			try {

+				rs = getSession(trans).execute(key==null?ps(trans):ps(trans).bind(key));

+/// TEST CODE for Exception				

+//				boolean force = true; 

+//				if(force) {

+//					Map<InetSocketAddress, Throwable> misa = new HashMap<InetSocketAddress,Throwable>();

+//					//misa.put(new InetSocketAddress(444),new Exception("no host was tried"));

+//					misa.put(new InetSocketAddress(444),new Exception("Connection has been closed"));

+//					throw new com.datastax.driver.core.exceptions.NoHostAvailableException(misa);

+////					throw new com.datastax.driver.core.exceptions.AuthenticationException(new InetSocketAddress(9999),"no host was tried");

+//				}

+//// END TEST CODE

+			} catch (DriverException | APIException | IOException e) {

+				AbsCassDAO.this.reportPerhapsReset(trans,e);

+				return Result.err(Status.ERR_Backend,"%s-%s executing %s",e.getClass().getName(),e.getMessage(), cql);

+			} finally {

+				tt.done();

+			}

+			

+			return extract(loader,rs,null /*let Array be created if necessary*/,dflt);

+		}

+		

+		public Result<List<DATA>> read(TRANS trans, String text, DATA data) {

+			return read(trans,text, loader.extract(data, size, crud));

+		}

+		

+		public Object[] keyFrom(DATA data) {

+			return loader.extract(data, size, CRUD.delete); // Delete is key only

+		}

+

+		/*

+		 * Note: in case PSInfos are deleted, we want to remove them from list.  This is not expected, 

+		 * but we don't want a data leak if it does.  Finalize doesn't have to happen quickly

+		 */

+		@Override

+		protected void finalize() throws Throwable {

+			psinfos.remove(this);

+		}

+	}

+

+	protected final Accept<DATA> dflt = new Accept<DATA>() {

+		@Override

+		public boolean ok(DATA data) {

+			return true;

+		}

+	};

+

+

+	@SuppressWarnings("unchecked")

+    protected final Result<List<DATA>> extract(Loader<DATA> loader, ResultSet rs, List<DATA> indata, Accept<DATA> accept) {

+		List<Row> rows = rs.all();

+		if(rows.isEmpty()) {

+			return Result.ok((List<DATA>)EMPTY); // Result sets now .emptyList(true);

+		} else {

+			DATA d;

+			List<DATA> data = indata==null?new ArrayList<DATA>(rows.size()):indata;

+			

+			for(Row row : rows) {

+				try {

+					d = loader.load(dataClass.newInstance(),row);

+					if(accept.ok(d)) {

+						data.add(d);

+					}

+				} catch(Exception e) {

+					return Result.err(e);

+				}

+			}

+			return Result.ok(data);

+		}

+    }

+    

+	private static final String NEW_CASSANDRA_SESSION_CREATED = "New Cassandra Session Created";

+	private static final String NEW_CASSANDRA_CLUSTER_OBJECT_CREATED = "New Cassandra Cluster Object Created";

+	private static final String NEW_CASSANDRA_SESSION = "New Cassandra Session";

+

+	private static class ResetRequest {

+		//package on purpose

+		Session session;

+		long timestamp;

+		

+		public ResetRequest(Session session) {

+			this.session = session;

+			timestamp = System.currentTimeMillis();

+		}

+	}

+

+	

+	public static final void primePSIs(TransStore trans) throws APIException, IOException {

+		for(AbsCassDAO<? extends TransStore, ?>.PSInfo psi : psinfos) {

+			if(psi.ps==null) {

+				psi.ps(trans);

+			}

+		}

+	}

+	

+	public final Session getSession(TransStore trans) throws APIException, IOException {

+		// Try to use Trans' session, if exists

+		if(sessionSlot!=null) { // try to get from Trans

+			Session sess = trans.get(sessionSlot, null);

+			if(sess!=null) {

+				return sess;

+			}

+		}

+		

+		// If there's an owning DAO, use it's session

+		if(owningDAO!=null) {

+			return owningDAO.getSession(trans);

+		}

+		

+		// OK, nothing else works... get our own.

+		if(session==null || resetTrigger) {

+			Cluster tempCluster = null;

+			Session tempSession = null;

+			try {

+				synchronized(NEW_CASSANDRA_SESSION_CREATED) {

+					boolean reset = false;

+					for(ResetRequest r : resetDeque) {

+						if(r.session == session) {

+							if(r.timestamp>nextAvailableReset) {

+								reset=true;

+								nextAvailableReset = System.currentTimeMillis() + 60000;

+								tempCluster = cluster;

+								tempSession = session;

+								break;

+							} else {

+								trans.warn().log("Cassandra Connection Reset Ignored: Recent Reset");

+							}

+						}

+					}

+	

+					if(reset || session == null) {

+						TimeTaken tt = trans.start(NEW_CASSANDRA_SESSION, Env.SUB);

+						try {

+							// Note: Maitrayee recommended not closing the cluster, just

+							// overwrite it. 9/30/2016 assuming same for Session

+							// This was a bad idea.  Ran out of File Handles as I suspected..

+							if(reset) {

+								for(AbsCassDAO<? extends TransStore, ?>.PSInfo psi : psinfos) {

+									psi.reset();

+								}

+							}

+							if(reset || cluster==null) {

+								cluster = CassAccess.cluster(trans, keyspace);

+								trans.warn().log(NEW_CASSANDRA_CLUSTER_OBJECT_CREATED);

+							}

+							if(reset || session==null) {

+								session = cluster.connect(keyspace);

+								trans.warn().log(NEW_CASSANDRA_SESSION_CREATED);

+							}

+						} finally {

+							resetTrigger=false;

+							tt.done();

+						}

+					}

+				}

+			} finally {

+				TimeTaken tt = trans.start("Clear Reset Deque", Env.SUB);

+				try {

+					resetDeque.clear();

+					// Not clearing Session/Cluster appears to kill off FileHandles

+					if(tempSession!=null && !tempSession.isClosed()) {

+						tempSession.close();

+					}

+					if(tempCluster!=null && !tempCluster.isClosed()) {

+						tempCluster.close();

+					}

+				} finally {

+					tt.done();

+				}

+			}

+		}

+		return session;

+	}

+	

+	public final boolean reportPerhapsReset(TransStore trans, Exception e) {

+		if(owningDAO!=null) {

+			return owningDAO.reportPerhapsReset(trans, e);

+		} else {

+			boolean rv = false;

+			if(CassAccess.isResetException(e)) {

+				trans.warn().printf("Session Reset called for %s by %s ",session==null?"":session,e==null?"Mgmt Command":e.getClass().getName());

+				resetDeque.addFirst(new ResetRequest(session));

+				rv = resetTrigger = true;

+			} 

+			trans.error().log(e);

+			return rv;

+		}

+	}

+

+	public void close(TransStore trans) {

+		if(owningDAO==null) {

+			if(session!=null) {

+				TimeTaken tt = trans.start("Cassandra Session Close", Env.SUB);

+				try {

+					session.close();

+				} finally {

+					tt.done();

+				}

+				session = null;

+			} else {

+				trans.debug().log("close called(), Session already closed");

+			}

+		} else {

+			owningDAO.close(trans);

+		}

+	}

+

+	protected void wasModified(TRANS trans, CRUD modified, DATA data, String ... override) {

+	}

+	

+	protected interface Accept<DATA> {

+		public boolean ok(DATA data);

+	}

+

+}

+

+

+

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Bytification.java b/authz-cass/src/main/java/org/onap/aaf/dao/Bytification.java
new file mode 100644
index 0000000..901339e
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Bytification.java
@@ -0,0 +1,31 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+

+public interface Bytification {

+	public ByteBuffer bytify() throws IOException;

+	public void reconstitute(ByteBuffer bb) throws IOException;

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/CIDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/CIDAO.java
new file mode 100644
index 0000000..05bb86d
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/CIDAO.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.util.Date;

+

+import org.onap.aaf.authz.layer.Result;

+

+import org.onap.aaf.inno.env.Trans;

+

+public interface CIDAO<TRANS extends Trans> {

+

+	/**

+	 * Touch the date field for given Table

+	 *  

+	 * @param trans

+	 * @param name

+	 * @return

+	 */

+	public abstract Result<Void> touch(TRANS trans, String name, int ... seg);

+

+	/**

+	 * Read all Info entries, and set local Date objects

+	 * 

+	 * This is to support regular data checks on the Database to speed up Caching behavior

+	 * 

+	 */

+	public abstract Result<Void> check(TRANS trans);

+

+	public abstract Date get(TRANS trans, String table, int seg);

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Cacheable.java b/authz-cass/src/main/java/org/onap/aaf/dao/Cacheable.java
new file mode 100644
index 0000000..0848292
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Cacheable.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+/**

+ * Interface to obtain Segment Integer from DAO Data

+ * for use in Caching mechanism

+ * 

+ * This should typically be obtained by getting the Hash of the key, then using modulus on the size of segment.

+ * 

+ *

+ */

+public interface Cacheable {

+	public int[] invalidate(Cached<?,?> cache);

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Cached.java b/authz-cass/src/main/java/org/onap/aaf/dao/Cached.java
new file mode 100644
index 0000000..5e5323c
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Cached.java
@@ -0,0 +1,198 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.util.Date;

+import java.util.List;

+import java.util.Map;

+import java.util.Timer;

+import java.util.TimerTask;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cache.Cache;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Trans;

+

+public class Cached<TRANS extends Trans, DATA extends Cacheable> extends Cache<TRANS,DATA> {

+	// Java does not allow creation of Arrays with Generics in them...

+	// private Map<String,Dated> cache[];

+	protected final CIDAO<TRANS> info;

+	

+	private static Timer infoTimer;

+	private Object cache[];

+	public final int segSize;

+

+	protected final String name;

+	

+

+

+	// Taken from String Hash, but coded, to ensure consistent across Java versions.  Also covers negative case;

+	public int cacheIdx(String key) {

+		int h = 0;

+		for (int i = 0; i < key.length(); i++) {

+		    h = 31*h + key.charAt(i);

+		}

+		if(h<0)h*=-1;

+		return h%segSize;

+	}

+	

+	public Cached(CIDAO<TRANS> info, String name, int segSize) {

+		this.name =name;

+		this.segSize = segSize;

+		this.info = info;

+		cache = new Object[segSize];

+		// Create a new Map for each Segment, and store locally

+		for(int i=0;i<segSize;++i) {

+			cache[i]=obtain(name+i);

+		}

+	}

+	

+	public void add(String key, List<DATA> data) {

+		@SuppressWarnings("unchecked")

+		Map<String,Dated> map = ((Map<String,Dated>)cache[cacheIdx(key)]);

+		map.put(key, new Dated(data));

+	}

+

+

+	public int invalidate(String key)  {

+		int cacheIdx = cacheIdx(key);

+		@SuppressWarnings("unchecked")

+		Map<String,Dated> map = ((Map<String,Dated>)cache[cacheIdx]);

+//		if(map.remove(key)!=null) // Not seeming to remove all the time

+		if(map!=null)map.clear();

+//			System.err.println("Remove " + name + " " + key);

+		return cacheIdx;

+	}

+

+	public Result<Void> invalidate(int segment)  {

+		if(segment<0 || segment>=cache.length) return Result.err(Status.ERR_BadData,"Cache Segment %s is out of range",Integer.toString(segment));

+		@SuppressWarnings("unchecked")

+		Map<String,Dated> map = ((Map<String,Dated>)cache[segment]);

+		if(map!=null) {

+			map.clear();

+		}

+		return Result.ok();

+	}

+

+	protected interface Getter<D> {

+		public abstract Result<List<D>> get();

+	};

+	

+	// TODO utilize Segmented Caches, and fold "get" into "reads"

+	@SuppressWarnings("unchecked")

+	public Result<List<DATA>> get(TRANS trans, String key, Getter<DATA> getter) {

+		List<DATA> ld = null;

+		Result<List<DATA>> rld = null;

+		

+		int cacheIdx = cacheIdx(key);

+		Map<String, Dated> map = ((Map<String,Dated>)cache[cacheIdx]);

+		

+		// Check for saved element in cache

+		Dated cached = map.get(key);

+		// Note: These Segment Timestamps are kept up to date with DB

+		Date dbStamp = info.get(trans, name,cacheIdx);

+		

+		// Check for cache Entry and whether it is still good (a good Cache Entry is same or after DBEntry, so we use "before" syntax)

+		if(cached!=null && dbStamp.before(cached.timestamp)) {

+			ld = (List<DATA>)cached.data;

+			rld = Result.ok(ld);

+		} else {

+			rld = getter.get();

+			if(rld.isOK()) { // only store valid lists

+				map.put(key, new Dated(rld.value));  // successful item found gets put in cache

+//			} else if(rld.status == Result.ERR_Backend){

+//				map.remove(key);

+			}

+		}

+		return rld;

+	}

+

+	/**

+	 * Each Cached object has multiple Segments that need cleaning.  Derive each, and add to Cleansing Thread

+	 * @param env

+	 * @param dao

+	 */

+	public static void startCleansing(AuthzEnv env, CachedDAO<?,?,?> ... dao) {

+		for(CachedDAO<?,?,?> d : dao) {  

+			for(int i=0;i<d.segSize;++i) {

+				startCleansing(env, d.table()+i);

+			}

+		}

+	}

+

+

+	public static<T extends Trans> void startRefresh(AuthzEnv env, CIDAO<AuthzTrans> cidao) {

+		if(infoTimer==null) {

+			infoTimer = new Timer("CachedDAO Info Refresh Timer");

+			int minRefresh = 10*1000*60; // 10 mins Integer.parseInt(env.getProperty(CACHE_MIN_REFRESH_INTERVAL,"2000")); // 2 second minimum refresh 

+			infoTimer.schedule(new Refresh(env,cidao, minRefresh), 1000, minRefresh); // note: Refresh from DB immediately

+		}

+	}

+	

+	public static void stopTimer() {

+		Cache.stopTimer();

+		if(infoTimer!=null) {

+			infoTimer.cancel();

+			infoTimer = null;

+		}

+	}

+	

+	private final static class Refresh extends TimerTask {

+		private static final int maxRefresh = 2*60*10000; // 20 mins

+		private AuthzEnv env;

+		private CIDAO<AuthzTrans> cidao;

+		private int minRefresh;

+		private long lastRun;

+		

+		public Refresh(AuthzEnv env, CIDAO<AuthzTrans> cidao, int minRefresh) {

+			this.env = env;

+			this.cidao = cidao;

+			this.minRefresh = minRefresh;

+			lastRun = System.currentTimeMillis()-maxRefresh-1000;

+		}

+		

+		@Override

+		public void run() {

+			// Evaluate whether to refresh based on transaction rate

+			long now = System.currentTimeMillis();

+			long interval = now-lastRun;

+

+			if(interval < minRefresh || interval < Math.min(env.transRate(),maxRefresh)) return;

+			lastRun = now;

+			AuthzTrans trans = env.newTransNoAvg();

+			Result<Void> rv = cidao.check(trans);

+			if(rv.status!=Result.OK) {

+				env.error().log("Error in CacheInfo Refresh",rv.details);

+			}

+			if(env.debug().isLoggable()) {

+				StringBuilder sb = new StringBuilder("Cache Info Refresh: ");

+				trans.auditTrail(0, sb, Env.REMOTE);

+				env.debug().log(sb);

+			}

+		}

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/CachedDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/CachedDAO.java
new file mode 100644
index 0000000..4237b91
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/CachedDAO.java
@@ -0,0 +1,229 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * CachedDAO

+ * 

+ * Cache the response of "get" of any DAO.  

+ * 

+ * For simplicity's sake, at this time, we only do this for single Object keys  

+ * 

+ *

+ * @param <DATA>

+ */

+public class CachedDAO<TRANS extends Trans,D extends DAO<TRANS,DATA>,DATA extends Cacheable> 

+		extends Cached<TRANS,DATA> implements DAO_RO<TRANS,DATA>{

+//	private final String dirty_str; 

+	

+	private final D dao;

+

+	public CachedDAO(D dao, CIDAO<TRANS> info, int segsize) {

+		super(info, dao.table(), segsize);

+		

+		// Instantiate a new Cache per DAO name (so separate instances use the same cache) 

+		this.dao = dao;

+		//read_str = "Cached READ for " + dao.table();

+//		dirty_str = "Cache DIRTY on " + dao.table();

+		if(dao instanceof CassDAOImpl) {

+			((CassDAOImpl<?,?>)dao).cache = this;

+		}

+	}

+	

+	public static<T extends Trans, DA extends DAO<T,DT>, DT extends Cacheable> 

+			CachedDAO<T,DA,DT> create(DA dao, CIDAO<T> info, int segsize) {

+		return new CachedDAO<T,DA,DT>(dao,info, segsize);

+	}

+

+	public void add(DATA data)  {

+		String key = keyFromObjs(dao.keyFrom(data));

+		List<DATA> list = new ArrayList<DATA>();

+		list.add(data);

+		super.add(key,list);

+	}

+	

+//	public void invalidate(TRANS trans, Object ... objs)  {

+//		TimeTaken tt = trans.start(dirty_str, Env.SUB);

+//		try {

+//			super.invalidate(keyFromObjs(objs));

+//		} finally {

+//			tt.done();

+//		}

+//	}

+

+	public static String keyFromObjs(Object ... objs) {

+		String key;

+		if(objs.length==1 && objs[0] instanceof String) {

+			key = (String)objs[0];

+		} else {

+			StringBuilder sb = new StringBuilder();

+			boolean first = true;

+			for(Object o : objs) {

+				if(o!=null) {

+					if(first) {

+					    first =false;

+					} else {

+					    sb.append('|');

+					}

+					sb.append(o.toString());

+				}

+			}

+			key = sb.toString();

+		}

+		return key;

+	}

+

+	public Result<DATA> create(TRANS trans, DATA data) {

+		Result<DATA> d = dao.create(trans,data);

+		if(d.status==Status.OK) {

+		    add(d.value);

+		} else {

+			trans.error().log(d.errorString());

+		}

+		invalidate(trans,data);

+		return d;

+	}

+

+	protected class DAOGetter implements Getter<DATA> {

+		protected TRANS trans;

+		protected Object objs[];

+		protected D dao;

+		public Result<List<DATA>> result;

+

+		public DAOGetter(TRANS trans, D dao, Object ... objs) {

+			this.trans = trans;

+			this.dao = dao;

+			this.objs = objs;

+		}

+		

+		/**

+		 * Separated into single call for easy overloading

+		 * @return

+		 */

+		public Result<List<DATA>> call() {

+			return dao.read(trans, objs);

+		}

+		

+		@Override

+		public final Result<List<DATA>> get() {

+			return call();

+//			if(result.isOKhasData()) { // Note, given above logic, could exist, but stale

+//				return result.value;

+//			} else {

+//				return null;

+//			}

+		}

+	}

+

+	@Override

+	public Result<List<DATA>> read(final TRANS trans, final Object ... objs) {

+		DAOGetter getter = new DAOGetter(trans,dao,objs); 

+		return get(trans, keyFromObjs(objs),getter);

+//		if(ld!=null) {

+//			return Result.ok(ld);//.emptyList(ld.isEmpty());

+//		}

+//		// Result Result if exists

+//		if(getter.result==null) {

+//			return Result.err(Status.ERR_NotFound, "No Cache or Lookup found on [%s]",dao.table());

+//		}

+//		return getter.result;

+	}

+

+	// Slight Improved performance available when String and Obj versions are known. 

+	public Result<List<DATA>> read(final String key, final TRANS trans, final Object ... objs) {

+		DAOGetter getter = new DAOGetter(trans,dao,objs); 

+		return get(trans, key, getter);

+//		if(ld!=null) {

+//			return Result.ok(ld);//.emptyList(ld.isEmpty());

+//		}

+//		// Result Result if exists

+//		if(getter.result==null) {

+//			return Result.err(Status.ERR_NotFound, "No Cache or Lookup found on [%s]",dao.table());

+//		}

+//		return getter.result;

+	}

+	

+	@Override

+	public Result<List<DATA>> read(TRANS trans, DATA data) {

+		return read(trans,dao.keyFrom(data));

+	}

+	public Result<Void> update(TRANS trans, DATA data) {

+		Result<Void> d = dao.update(trans, data);

+		if(d.status==Status.OK) {

+		    add(data);

+		} else {

+			trans.error().log(d.errorString());

+		}

+		return d;

+	}

+

+	public Result<Void> delete(TRANS trans, DATA data, boolean reread) {

+		if(reread) { // If reread, get from Cache, if possible, not DB exclusively

+			Result<List<DATA>> rd = read(trans,data);

+			if(rd.notOK()) {

+			    return Result.err(rd);

+			} else {

+				trans.error().log(rd.errorString());

+			}

+			if(rd.isEmpty()) {

+				data.invalidate(this);

+				return Result.err(Status.ERR_NotFound,"Not Found");

+			}

+			data = rd.value.get(0);

+		}

+		Result<Void> rv=dao.delete(trans, data, false);

+		data.invalidate(this);

+		return rv;

+	}

+	

+	@Override

+	public void close(TRANS trans) {

+		if(dao!=null) {

+		    dao.close(trans);

+		}

+	}

+	

+

+	@Override

+	public String table() {

+		return dao.table();

+	}

+	

+	public D dao() {

+		return dao;

+	}

+	

+	public void invalidate(TRANS trans, DATA data) {

+        if(info.touch(trans, dao.table(),data.invalidate(this)).notOK()) {

+	    trans.error().log("Cannot touch CacheInfo for Role");

+	}

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/CassAccess.java b/authz-cass/src/main/java/org/onap/aaf/dao/CassAccess.java
new file mode 100644
index 0000000..79bd6e0
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/CassAccess.java
@@ -0,0 +1,220 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+

+import org.onap.aaf.cadi.routing.GreatCircle;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.util.Split;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Cluster.Builder;

+import com.datastax.driver.core.policies.DCAwareRoundRobinPolicy;

+

+public class CassAccess {

+	public static final String KEYSPACE = "authz";

+	public static final String CASSANDRA_CLUSTERS = "cassandra.clusters";

+	public static final String CASSANDRA_CLUSTERS_PORT = "cassandra.clusters.port";

+	public static final String CASSANDRA_CLUSTERS_USER_NAME = "cassandra.clusters.user";

+	public static final String CASSANDRA_CLUSTERS_PASSWORD = "cassandra.clusters.password";

+	public static final String CASSANDRA_RESET_EXCEPTIONS = "cassandra.reset.exceptions";

+	public static final String LATITUDE = "LATITUDE";

+	public static final String LONGITUDE = "LONGITUDE";

+	private static final List<Resettable> resetExceptions = new ArrayList<Resettable>();

+	public static final String ERR_ACCESS_MSG = "Accessing Backend";

+	private static Builder cb = null;

+

+	/**

+	 * To create DCAwareRoundRobing Policy:

+	 * 	 Need Properties

+	 * 		LATITUDE (or AFT_LATITUDE)

+	 * 		LONGITUDE (or AFT_LONGITUDE)

+	 * 		CASSANDRA CLUSTERS with additional information:

+	 * 			machine:DC:lat:long,machine:DC:lat:long

+	 * @param env

+	 * @param prefix

+	 * @return

+	 * @throws APIException

+	 * @throws IOException

+	 */

+

+	@SuppressWarnings("deprecation")

+	public static synchronized Cluster cluster(Env env, String prefix) throws APIException, IOException {

+		if(cb == null) {

+			String pre;

+			if(prefix==null) {

+				pre="";

+			} else {

+				env.info().log("Cassandra Connection for ",prefix);

+				pre = prefix+'.';

+			}

+			cb = Cluster.builder();

+			String str = env.getProperty(pre+CASSANDRA_CLUSTERS_PORT,"9042");

+			if(str!=null) {

+				env.init().log("Cass Port = ",str );

+				cb.withPort(Integer.parseInt(str));

+			}

+			str = env.getProperty(pre+CASSANDRA_CLUSTERS_USER_NAME,null);

+			if(str!=null) {

+				env.init().log("Cass User = ",str );

+				String epass = env.getProperty(pre + CASSANDRA_CLUSTERS_PASSWORD,null);

+				if(epass==null) {

+					throw new APIException("No Password configured for " + str);

+				}

+				//TODO Figure out way to ensure Decryptor setting in AuthzEnv

+				if(env instanceof AuthzEnv) {

+					cb.withCredentials(str,((AuthzEnv)env).decrypt(epass,true));

+				} else {

+					cb.withCredentials(str, env.decryptor().decrypt(epass));

+				}

+			}

+	

+			str = env.getProperty(pre+CASSANDRA_RESET_EXCEPTIONS,null);

+			if(str!=null) {

+				env.init().log("Cass ResetExceptions = ",str );

+				for(String ex : Split.split(',', str)) {

+					resetExceptions.add(new Resettable(env,ex));

+				}

+			}

+	

+			str = env.getProperty(LATITUDE,env.getProperty("AFT_LATITUDE",null));

+			Double lat = str!=null?Double.parseDouble(str):null;

+			str = env.getProperty(LONGITUDE,env.getProperty("AFT_LONGITUDE",null));

+			Double lon = str!=null?Double.parseDouble(str):null;

+			if(lat == null || lon == null) {

+				throw new APIException("LATITUDE(or AFT_LATITUDE) and/or LONGITUDE(or AFT_LATITUDE) are not set");

+			}

+			

+			env.init().printf("Service Latitude,Longitude = %f,%f",lat,lon);

+			

+			str = env.getProperty(pre+CASSANDRA_CLUSTERS,"localhost");

+			env.init().log("Cass Clusters = ",str );

+			String[] machs = Split.split(',', str);

+			String[] cpoints = new String[machs.length];

+			String bestDC = null;

+			int numInBestDC = 1;

+			double mlat, mlon,temp,distance = -1.0;

+			for(int i=0;i<machs.length;++i) {

+				String[] minfo = Split.split(':',machs[i]);

+				if(minfo.length>0) {

+					cpoints[i]=minfo[0];

+				}

+			

+				// Calc closest DC with Great Circle

+				if(minfo.length>3) {

+					mlat = Double.parseDouble(minfo[2]);

+					mlon = Double.parseDouble(minfo[3]);

+					if((temp=GreatCircle.calc(lat, lon, mlat, mlon)) > distance) {

+						distance = temp;

+						if(bestDC!=null && bestDC.equals(minfo[1])) {

+							++numInBestDC;

+						} else {

+							bestDC = minfo[1];

+							numInBestDC = 1;

+						}

+					} else {

+						if(bestDC!=null && bestDC.equals(minfo[1])) {

+							++numInBestDC;

+						}

+					}

+				}

+			}

+			

+			cb.addContactPoints(cpoints);

+			

+			if(bestDC!=null) {

+				// 8/26/2016 Management has determined that Accuracy is preferred over speed in bad situations

+				// Local DC Aware Load Balancing appears to have the highest normal performance, with the best

+				// Degraded Accuracy

+				cb.withLoadBalancingPolicy(new DCAwareRoundRobinPolicy(

+						bestDC, numInBestDC, true /*allow LocalDC to look at other DCs for LOCAL_QUORUM */));

+				env.init().printf("Cassandra configured for DCAwareRoundRobinPolicy at %s with emergency remote of up to %d node(s)"

+					,bestDC, numInBestDC);

+			} else {

+				env.init().printf("Cassandra is using Default Policy, which is not DC aware");

+			}

+		}

+		return cb.build();

+	}

+	

+	private static class Resettable {

+		private Class<? extends Exception> cls;

+		private List<String> messages;

+		

+		@SuppressWarnings("unchecked")

+		public Resettable(Env env, String propData) throws APIException {

+			if(propData!=null && propData.length()>1) {

+				String[] split = Split.split(':', propData);

+				if(split.length>0) {

+					try {

+						cls = (Class<? extends Exception>)Class.forName(split[0]);

+					} catch (ClassNotFoundException e) {

+						throw new APIException("Declared Cassandra Reset Exception, " + propData + ", cannot be ClassLoaded");

+					}

+				}

+				if(split.length>1) {

+					messages=new ArrayList<String>();

+					for(int i=1;i<split.length;++i) {

+						String str = split[i];

+						int start = str.startsWith("\"")?1:0;

+						int end = str.length()-(str.endsWith("\"")?1:0);

+						messages.add(split[i].substring(start, end));

+					}

+				} else {

+					messages = null;

+				}

+			}

+		}

+		

+		public boolean matches(Exception ex) {

+			if(ex.getClass().equals(cls)) {

+				if(messages!=null) {

+					String msg = ex.getMessage();

+					for(String m : messages) {

+						if(msg.contains(m)) {

+							return true;

+						}

+					}

+				}

+			}

+			return false;

+		}

+	}

+	

+	public static final boolean isResetException(Exception e) {

+		if(e==null) {

+			return true;

+		}

+		for(Resettable re : resetExceptions) {

+			if(re.matches(e)) {

+				return true;

+			}

+		}

+		return false;

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/CassDAOImpl.java b/authz-cass/src/main/java/org/onap/aaf/dao/CassDAOImpl.java
new file mode 100644
index 0000000..61db914
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/CassDAOImpl.java
@@ -0,0 +1,328 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.ByteArrayInputStream;

+import java.io.DataInputStream;

+import java.lang.reflect.Field;

+import java.nio.ByteBuffer;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.inno.env.TransStore;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ConsistencyLevel;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.ResultSetFuture;

+

+/**

+ * AbsCassDAO

+ *

+ * Deal with the essentials of Interaction with Cassandra DataStore for all Cassandra DAOs

+ *

+ *

+ * @param <DATA>

+ */

+public class CassDAOImpl<TRANS extends TransStore,DATA> extends AbsCassDAO<TRANS, DATA> implements DAO<TRANS,DATA> {

+	public static final String USER_NAME = "__USER_NAME__";

+	protected static final String CREATE_SP = "CREATE ";

+	protected static final String UPDATE_SP = "UPDATE ";

+	protected static final String DELETE_SP = "DELETE ";

+	protected static final String SELECT_SP = "SELECT ";

+

+	protected final String C_TEXT = getClass().getSimpleName() + " CREATE";

+	protected final String R_TEXT = getClass().getSimpleName() + " READ";

+	protected final String U_TEXT = getClass().getSimpleName() + " UPDATE";

+	protected final String D_TEXT = getClass().getSimpleName() + " DELETE";

+	private String table;

+	

+	protected final ConsistencyLevel readConsistency,writeConsistency;

+	

+	// Setteable only by CachedDAO

+	protected Cached<?, ?> cache;

+

+	/**

+	 * A Constructor from the originating Cluster.  This DAO will open the Session at need,

+	 * and shutdown the session when "close()" is called.

+	 *

+	 * @param cluster

+	 * @param keyspace

+	 * @param dataClass

+	 */

+	public CassDAOImpl(TRANS trans, String name, Cluster cluster, String keyspace, Class<DATA> dataClass, String table, ConsistencyLevel read, ConsistencyLevel write) {

+		super(trans, name, cluster,keyspace,dataClass);

+		this.table = table;

+		readConsistency = read;

+		writeConsistency = write;

+	}

+	

+	/**

+	 * A Constructor to share Session with other DAOs.

+	 *

+	 * This method get the Session and Cluster information from the calling DAO, and won't

+	 * touch the Session on closure.

+	 *

+	 * @param aDao

+	 * @param dataClass

+	 */

+	public CassDAOImpl(TRANS trans, String name, AbsCassDAO<TRANS,?> aDao, Class<DATA> dataClass, String table, ConsistencyLevel read, ConsistencyLevel write) {

+		super(trans, name, aDao,dataClass);

+		this.table = table;

+		readConsistency = read;

+		writeConsistency = write;

+	}

+

+	protected PSInfo createPS;

+	protected PSInfo readPS;

+	protected PSInfo updatePS;

+	protected PSInfo deletePS;

+	private boolean async=false;

+

+	public void async(boolean bool) {

+		async = bool;

+	}

+

+	public final String[] setCRUD(TRANS trans, String table, Class<?> dc,Loader<DATA> loader) {

+		return setCRUD(trans, table, dc, loader, -1);

+	}

+	

+	public final String[] setCRUD(TRANS trans, String table, Class<?> dc,Loader<DATA> loader, int max) {

+				Field[] fields = dc.getDeclaredFields();

+				int end = max>=0 & max<fields.length?max:fields.length;

+				// get keylimit from a non-null Loader

+				int keylimit = loader.keylimit();

+			

+				StringBuilder sbfc = new StringBuilder();

+				StringBuilder sbq = new StringBuilder();

+				StringBuilder sbwc = new StringBuilder();

+				StringBuilder sbup = new StringBuilder();

+			

+				if(keylimit>0) {

+					for(int i=0;i<end;++i) {

+						if(i>0) {

+							sbfc.append(',');

+							sbq.append(',');

+							if(i<keylimit) {

+								sbwc.append(" AND ");

+							}

+						}

+						sbfc.append(fields[i].getName());

+						sbq.append('?');

+						if(i>=keylimit) {

+							if(i>keylimit) {

+								sbup.append(',');

+							}

+							sbup.append(fields[i].getName());

+							sbup.append("=?");

+						}

+						if(i<keylimit) {

+							sbwc.append(fields[i].getName());

+							sbwc.append("=?");

+						}

+					}

+			

+					createPS = new PSInfo(trans, "INSERT INTO " + table + " ("+ sbfc +") VALUES ("+ sbq +");",loader,writeConsistency);

+			

+					readPS = new PSInfo(trans, "SELECT " + sbfc + " FROM " + table + " WHERE " + sbwc + ';',loader,readConsistency);

+			

+					// Note: UPDATES can't compile if there are no fields besides keys... Use "Insert"

+					if(sbup.length()==0) {

+						updatePS = createPS; // the same as an insert

+					} else {

+						updatePS = new PSInfo(trans, "UPDATE " + table + " SET " + sbup + " WHERE " + sbwc + ';',loader,writeConsistency);

+					}

+			

+					deletePS = new PSInfo(trans, "DELETE FROM " + table + " WHERE " + sbwc + ';',loader,writeConsistency);

+				}

+				return new String[] {sbfc.toString(), sbq.toString(), sbup.toString(), sbwc.toString()};

+			}

+

+	public void replace(CRUD crud, PSInfo psInfo) {

+		switch(crud) {

+			case create: createPS = psInfo; break;

+			case read:   readPS = psInfo; break;

+			case update: updatePS = psInfo; break;

+			case delete: deletePS = psInfo; break;

+		}

+	}

+

+	public void disable(CRUD crud) {

+		switch(crud) {

+			case create: createPS = null; break;

+			case read:   readPS = null; break;

+			case update: updatePS = null; break;

+			case delete: deletePS = null; break;

+		}

+	}

+

+	

+	/**

+	 * Given a DATA object, extract the individual elements from the Data into an Object Array for the

+	 * execute element.

+	 */

+	public Result<DATA> create(TRANS trans, DATA data)  {

+		if(createPS==null) {

+			Result.err(Result.ERR_NotImplemented,"Create is disabled for %s",getClass().getSimpleName());

+		}

+		if(async) /*ResultSetFuture */ {

+			Result<ResultSetFuture> rs = createPS.execAsync(trans, C_TEXT, data);

+			if(rs.notOK()) {

+				return Result.err(rs);

+			}

+		} else {

+			Result<ResultSet> rs = createPS.exec(trans, C_TEXT, data);

+			if(rs.notOK()) {

+				return Result.err(rs);

+			}

+		}

+		wasModified(trans, CRUD.create, data);

+		return Result.ok(data);

+	}

+

+	/**

+	 * Read the Unique Row associated with Full Keys

+	 */

+	public Result<List<DATA>> read(TRANS trans, DATA data) {

+		if(readPS==null) {

+			Result.err(Result.ERR_NotImplemented,"Read is disabled for %s",getClass().getSimpleName());

+		}

+		return readPS.read(trans, R_TEXT, data);

+	}

+

+	public Result<List<DATA>> read(TRANS trans, Object ... key) {

+		if(readPS==null) {

+			Result.err(Result.ERR_NotImplemented,"Read is disabled for %s",getClass().getSimpleName());

+		}

+		return readPS.read(trans, R_TEXT, key);

+	}

+

+	public Result<Void> update(TRANS trans, DATA data) {

+		if(updatePS==null) {

+			Result.err(Result.ERR_NotImplemented,"Update is disabled for %s",getClass().getSimpleName());

+		}

+		if(async)/* ResultSet rs =*/ {

+			Result<ResultSetFuture> rs = updatePS.execAsync(trans, U_TEXT, data);

+			if(rs.notOK()) {

+				return Result.err(rs);

+			}

+		} else {

+			Result<ResultSet> rs = updatePS.exec(trans, U_TEXT, data);

+			if(rs.notOK()) {

+				return Result.err(rs);

+			}

+		}

+		

+		wasModified(trans, CRUD.update, data);

+		return Result.ok();

+	}

+

+	// This method Sig for Cached...

+	public Result<Void> delete(TRANS trans, DATA data, boolean reread) {

+		if(deletePS==null) {

+			Result.err(Result.ERR_NotImplemented,"Delete is disabled for %s",getClass().getSimpleName());

+		}

+		// Since Deleting will be stored off, for possible re-constitution, need the whole thing

+		if(reread) {

+			Result<List<DATA>> rd = read(trans,data);

+			if(rd.notOK()) {

+				return Result.err(rd);

+			}

+			if(rd.isEmpty()) {

+				return Result.err(Status.ERR_NotFound,"Not Found");

+			}

+			for(DATA d : rd.value) { 

+				if(async) {

+					Result<ResultSetFuture> rs = deletePS.execAsync(trans, D_TEXT, d);

+					if(rs.notOK()) {

+						return Result.err(rs);

+					}

+				} else {

+					Result<ResultSet> rs = deletePS.exec(trans, D_TEXT, d);

+					if(rs.notOK()) {

+						return Result.err(rs);

+					}

+				}

+				wasModified(trans, CRUD.delete, d);

+			}

+		} else {

+			if(async)/* ResultSet rs =*/ {

+				Result<ResultSetFuture> rs = deletePS.execAsync(trans, D_TEXT, data);

+				if(rs.notOK()) {

+					return Result.err(rs);

+				}

+			} else {

+				Result<ResultSet> rs = deletePS.exec(trans, D_TEXT, data);

+				if(rs.notOK()) {

+					return Result.err(rs);

+				}

+			}

+			wasModified(trans, CRUD.delete, data);

+		}

+		return Result.ok();

+	}

+	

+	public final Object[] keyFrom(DATA data) {

+		return createPS.keyFrom(data);

+	}

+

+	@Override

+	public String table() {

+		return table;

+	}

+	

+	public static final String CASS_READ_CONSISTENCY="cassandra.readConsistency";

+	public static final String CASS_WRITE_CONSISTENCY="cassandra.writeConsistency";

+	protected static ConsistencyLevel readConsistency(AuthzTrans trans, String table) {

+		String prop = trans.getProperty(CASS_READ_CONSISTENCY+'.'+table);

+		if(prop==null) {

+			prop = trans.getProperty(CASS_READ_CONSISTENCY);

+			if(prop==null) {

+				return ConsistencyLevel.ONE; // this is Cassandra Default

+			}

+		}

+		return ConsistencyLevel.valueOf(prop);

+	}

+

+	protected static ConsistencyLevel writeConsistency(AuthzTrans trans, String table) {

+		String prop = trans.getProperty(CASS_WRITE_CONSISTENCY+'.'+table);

+		if(prop==null) {

+			prop = trans.getProperty(CASS_WRITE_CONSISTENCY);

+			if(prop==null) {

+				return ConsistencyLevel.ONE; // this is Cassandra Default\

+			}

+		}

+		return ConsistencyLevel.valueOf(prop);

+	}

+

+	public static DataInputStream toDIS(ByteBuffer bb) {

+		byte[] b = bb.array();

+		return new DataInputStream(

+			new ByteArrayInputStream(b,bb.position(),bb.limit())

+		);

+	}

+

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/DAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/DAO.java
new file mode 100644
index 0000000..acdb36d
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/DAO.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import org.onap.aaf.authz.layer.Result;

+

+import org.onap.aaf.inno.env.Trans;

+

+

+/**

+ * DataAccessObject Interface

+ *

+ * Extend the ReadOnly form (for Get), and add manipulation methods

+ *

+ * @param <DATA>

+ */

+public interface DAO<TRANS extends Trans,DATA> extends DAO_RO<TRANS,DATA> {

+	public Result<DATA> create(TRANS trans, DATA data);

+	public Result<Void> update(TRANS trans, DATA data);

+	// In many cases, the data has been correctly read first, so we shouldn't read again

+	// Use reread=true if you are using DATA with only a Key

+	public Result<Void> delete(TRANS trans, DATA data, boolean reread);

+	public Object[] keyFrom(DATA data);

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/DAOException.java b/authz-cass/src/main/java/org/onap/aaf/dao/DAOException.java
new file mode 100644
index 0000000..85b8c84
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/DAOException.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+public class DAOException extends Exception {

+

+	/**

+	 * 

+	 */

+	private static final long serialVersionUID = 1527904125585539823L;

+

+//    // TODO -   enum in result class == is our intended design, currently the DAO layer does not use Result<RV> so we still use these for now

+//    public final static DAOException RoleNotFoundDAOException = new DAOException("RoleNotFound");

+//    public final static DAOException PermissionNotFoundDAOException = new DAOException("PermissionNotFound");

+//    public final static DAOException UserNotFoundDAOException = new DAOException("UserNotFound");

+

+    public DAOException() {

+	}

+

+	public DAOException(String message) {

+		super(message);

+	}

+

+	public DAOException(Throwable cause) {

+		super(cause);

+	}

+

+	public DAOException(String message, Throwable cause) {

+		super(message, cause);

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/DAO_RO.java b/authz-cass/src/main/java/org/onap/aaf/dao/DAO_RO.java
new file mode 100644
index 0000000..a853675
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/DAO_RO.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.util.List;

+

+import org.onap.aaf.authz.layer.Result;

+

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * DataAccessObject - ReadOnly

+ * 

+ * It is useful to have a ReadOnly part of the interface for CachedDAO

+ * 

+ * Normal DAOs will implement full DAO

+ * 

+ *

+ * @param <DATA>

+ */

+public interface DAO_RO<TRANS extends Trans,DATA> {

+	/**

+	 * Get a List of Data given Key of Object Array

+	 * @param objs

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<List<DATA>> read(TRANS trans, Object ... key);

+

+	/**

+	 * Get a List of Data given Key of DATA Object

+	 * @param trans

+	 * @param key

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<List<DATA>> read(TRANS trans, DATA key);

+

+	/**

+	 * close DAO

+	 */

+	public void close(TRANS trans);

+

+	/**

+	 * Return name of referenced Data

+	 * @return

+	 */

+	public String table();

+

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Loader.java b/authz-cass/src/main/java/org/onap/aaf/dao/Loader.java
new file mode 100644
index 0000000..42a73f4
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Loader.java
@@ -0,0 +1,214 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import com.datastax.driver.core.Row;

+

+public abstract class Loader<DATA> {

+	private int keylimit;

+	public Loader(int keylimit) {

+		this.keylimit = keylimit;

+	}

+	

+	public int keylimit() {

+		return keylimit;

+	}

+	

+	protected abstract DATA load(DATA data, Row row);

+	protected abstract void key(DATA data, int idx, Object[] obj);

+	protected abstract void body(DATA data, int idx, Object[] obj);

+

+	public final Object[] extract(DATA data, int size, CassDAOImpl.CRUD type) {

+		Object[] rv=null;

+		switch(type) {

+			case delete:

+				rv = new Object[keylimit()];

+				key(data,0,rv);

+				break;

+			case update:

+				rv = new Object[size];

+				body(data,0,rv);

+				int body = size-keylimit();

+				if(body>0) {

+				    key(data,body,rv);

+				}

+				break;

+			default:

+				rv = new Object[size];

+				key(data,0,rv);

+				if(size>keylimit()) {

+				    body(data,keylimit(),rv);

+				}

+				break;

+		}

+		return rv;

+	}

+	

+	public static void writeString(DataOutputStream os, String s) throws IOException {

+		if(s==null) {

+			os.writeInt(-1);

+		} else {

+			switch(s.length()) {

+				case 0:

+					os.writeInt(0);

+					break;

+				default:

+					byte[] bytes = s.getBytes();

+					os.writeInt(bytes.length);

+					os.write(bytes);

+			}

+		}

+	}

+	

+	/**

+	 * We use bytes here to set a Maximum

+	 * 

+	 * @param is

+	 * @param MAX

+	 * @return

+	 * @throws IOException

+	 */

+	public static String readString(DataInputStream is, byte[] _buff) throws IOException {

+		int l = is.readInt();

+		byte[] buff = _buff;

+		switch(l) {

+			case -1: return null;

+			case  0: return "";

+			default:

+				// Cover case where there is a large string, without always allocating a large buffer.

+				if(l>buff.length) {

+				    buff = new byte[l];

+				}

+				is.read(buff,0,l);

+				return new String(buff,0,l);

+		}

+	}

+

+	/**

+	 * Write a set with proper sizing

+	 * 

+	 * Note: at the moment, this is just String.  Probably can develop system where types

+	 * are supported too... but not now.

+	 * 

+	 * @param os

+	 * @param set

+	 * @throws IOException

+	 */

+	public static void writeStringSet(DataOutputStream os, Collection<String> set) throws IOException {

+		if(set==null) {

+			os.writeInt(-1);

+		} else {

+			os.writeInt(set.size());

+			for(String s : set) {

+				writeString(os, s);

+			}

+		}

+

+	}

+	

+	public static Set<String> readStringSet(DataInputStream is, byte[] buff) throws IOException {

+		int l = is.readInt();

+		if(l<0) {

+		    return null;

+		}

+		Set<String> set = new HashSet<String>(l);

+		for(int i=0;i<l;++i) {

+			set.add(readString(is,buff));

+		}

+		return set;

+	}

+	

+	public static List<String> readStringList(DataInputStream is, byte[] buff) throws IOException {

+		int l = is.readInt();

+		if(l<0) {

+		    return null;

+		}

+		List<String> list = new ArrayList<String>(l);

+		for(int i=0;i<l;++i) {

+			list.add(Loader.readString(is,buff));

+		}

+		return list;

+	}

+

+	/** 

+	 * Write a map

+	 * @param os

+	 * @param map

+	 * @throws IOException

+	 */

+	public static void writeStringMap(DataOutputStream os, Map<String,String> map) throws IOException {

+		if(map==null) {

+			os.writeInt(-1);

+		} else {

+			Set<Entry<String, String>> es = map.entrySet();

+			os.writeInt(es.size());

+			for(Entry<String,String> e : es) {

+				writeString(os, e.getKey());

+				writeString(os, e.getValue());

+			}

+		}

+

+	}

+

+	public static Map<String,String> readStringMap(DataInputStream is, byte[] buff) throws IOException {

+		int l = is.readInt();

+		if(l<0) {

+		    return null;

+		}

+		Map<String,String> map = new HashMap<String,String>(l);

+		for(int i=0;i<l;++i) {

+			String key = readString(is,buff);

+			map.put(key,readString(is,buff));

+		}

+		return map;

+	}

+	public static void writeHeader(DataOutputStream os, int magic, int version) throws IOException {

+		os.writeInt(magic);

+		os.writeInt(version);

+	}

+	

+	public static int readHeader(DataInputStream is, final int magic, final int version) throws IOException {

+		if(is.readInt()!=magic) {

+		    throw new IOException("Corrupted Data Stream");

+		}

+		int v = is.readInt();

+		if(version<0 || v>version) {

+		    throw new IOException("Unsupported Data Version: " + v);

+		}

+		return v;

+	}

+

+}

+

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Streamer.java b/authz-cass/src/main/java/org/onap/aaf/dao/Streamer.java
new file mode 100644
index 0000000..f645dd6
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Streamer.java
@@ -0,0 +1,32 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+

+public interface Streamer<DATA> {

+	public abstract void marshal(DATA data, DataOutputStream os) throws IOException;

+	public abstract void unmarshal(DATA data, DataInputStream is) throws IOException;

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/Touchable.java b/authz-cass/src/main/java/org/onap/aaf/dao/Touchable.java
new file mode 100644
index 0000000..dc3ab05
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/Touchable.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+public interface Touchable {

+	 // Or make all DAOs accept list of CIDAOs...

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCertDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCertDAO.java
new file mode 100644
index 0000000..567bd06
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCertDAO.java
@@ -0,0 +1,55 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+

+public class CachedCertDAO extends CachedDAO<AuthzTrans, CertDAO, CertDAO.Data> {

+	public CachedCertDAO(CertDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, CertDAO.CACHE_SEG);

+	}

+	

+	/**

+	 * Pass through Cert ID Lookup

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	

+	public Result<List<CertDAO.Data>> readID(AuthzTrans trans, final String id) {

+		return dao().readID(trans, id);

+	}

+	

+	public Result<List<CertDAO.Data>> readX500(AuthzTrans trans, final String x500) {

+		return dao().readX500(trans, x500);

+	}

+

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCredDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCredDAO.java
new file mode 100644
index 0000000..1467503
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedCredDAO.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+public class CachedCredDAO extends CachedDAO<AuthzTrans, CredDAO, CredDAO.Data> {

+	public CachedCredDAO(CredDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, CredDAO.CACHE_SEG);

+	}

+	

+	/**

+	 * Pass through Cred Lookup

+	 * 

+	 * Unlike Role and Perm, we don't need or want to cache these elements... Only used for NS Delete.

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<List<CredDAO.Data>> readNS(AuthzTrans trans, final String ns) {

+		

+		return dao().readNS(trans, ns);

+	}

+	

+	public Result<List<CredDAO.Data>> readID(AuthzTrans trans, final String id) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<CredDAO.Data>> call() {

+				return dao().readID(trans, id);

+			}

+		};

+		

+		Result<List<CredDAO.Data>> lurd = get(trans, id, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_UserNotFound,"No User Cred found");

+		}

+		return lurd;

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedNSDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedNSDAO.java
new file mode 100644
index 0000000..aae74e2
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedNSDAO.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+

+public class CachedNSDAO extends CachedDAO<AuthzTrans, NsDAO, NsDAO.Data> {

+	public CachedNSDAO(NsDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, NsDAO.CACHE_SEG);

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedPermDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedPermDAO.java
new file mode 100644
index 0000000..7d4c7fe
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedPermDAO.java
@@ -0,0 +1,125 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.PermDAO.Data;

+

+public class CachedPermDAO extends CachedDAO<AuthzTrans,PermDAO, PermDAO.Data> {

+

+	public CachedPermDAO(PermDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, PermDAO.CACHE_SEG);

+	}

+

+	public Result<List<Data>> readNS(AuthzTrans trans, final String ns) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				return dao.readNS(trans, ns);

+			}

+		};

+		

+		Result<List<Data>> lurd = get(trans, ns, getter);

+		if(lurd.isOKhasData()) {

+			return lurd;

+		} else {

+			

+		}

+//		if(getter.result==null) {

+//			if(lurd==null) {

+				return Result.err(Status.ERR_PermissionNotFound,"No Permission found - " + lurd.details);

+//			} else {

+//				return Result.ok(lurd);

+//			}

+//		}

+//		return getter.result;

+	}

+

+	public Result<List<Data>> readChildren(AuthzTrans trans, final String ns, final String type) {

+		return dao().readChildren(trans,ns,type);

+	}

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param type

+	 * @return

+	 */

+	public Result<List<Data>> readByType(AuthzTrans trans, final String ns, final String type) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				return dao.readByType(trans, ns, type);

+			}

+		};

+		

+		// Note: Can reuse index1 here, because there is no name collision versus response

+		Result<List<Data>> lurd = get(trans, ns+'|'+type, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound,"No Permission found");

+		}

+		return lurd;

+	}

+	

+	/**

+	 * Add desciption to this permission

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @param description

+	 * @return

+	 */

+	public Result<Void> addDescription(AuthzTrans trans, String ns, String type, 

+			String instance, String action, String description) {

+		//TODO Invalidate?

+		return dao().addDescription(trans, ns, type, instance, action, description);

+	}

+	

+	public Result<Void> addRole(AuthzTrans trans, PermDAO.Data perm, RoleDAO.Data role) {

+		Result<Void> rv = dao().addRole(trans,perm,role.encode());

+		if(trans.debug().isLoggable())

+			trans.debug().log("Adding",role.encode(),"to", perm, "with CachedPermDAO.addRole");

+		invalidate(trans,perm);

+		return rv;

+	}

+

+	public Result<Void> delRole(AuthzTrans trans, Data perm, RoleDAO.Data role) {

+		Result<Void> rv = dao().delRole(trans,perm,role.encode());

+		if(trans.debug().isLoggable())

+			trans.debug().log("Removing",role.encode(),"from", perm, "with CachedPermDAO.delRole");

+		invalidate(trans,perm);

+		return rv;

+	}

+

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedRoleDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedRoleDAO.java
new file mode 100644
index 0000000..788efbe
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedRoleDAO.java
@@ -0,0 +1,107 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.RoleDAO.Data;

+

+public class CachedRoleDAO extends CachedDAO<AuthzTrans,RoleDAO, RoleDAO.Data> {

+	public CachedRoleDAO(RoleDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, RoleDAO.CACHE_SEG);

+	}

+

+	public Result<List<Data>> readNS(AuthzTrans trans, final String ns) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				return dao.readNS(trans, ns);

+			}

+		};

+		

+		Result<List<Data>> lurd = get(trans, ns, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound,"No Role found");

+		}

+		return lurd;

+	}

+

+	public Result<List<Data>> readName(AuthzTrans trans, final String name) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				return dao().readName(trans, name);

+			}

+		};

+		

+		Result<List<Data>> lurd = get(trans, name, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound,"No Role found");

+		}

+		return lurd;

+	}

+

+	public Result<List<Data>> readChildren(AuthzTrans trans, final String ns, final String name) {

+		// At this point, I'm thinking it's better not to try to cache "*" results

+		// Data probably won't be accurate, and adding it makes every update invalidate most of the cache

+		// 2/4/2014

+		return dao().readChildren(trans,ns,name);

+	}

+

+	public Result<Void> addPerm(AuthzTrans trans, RoleDAO.Data rd, PermDAO.Data perm) {

+		Result<Void> rv = dao().addPerm(trans,rd,perm);

+		if(trans.debug().isLoggable())

+			trans.debug().log("Adding",perm,"to", rd, "with CachedRoleDAO.addPerm");

+		invalidate(trans, rd);

+		return rv;

+	}

+

+	public Result<Void> delPerm(AuthzTrans trans, RoleDAO.Data rd, PermDAO.Data perm) {

+		Result<Void> rv = dao().delPerm(trans,rd,perm);

+		if(trans.debug().isLoggable())

+			trans.debug().log("Removing",perm,"from", rd, "with CachedRoleDAO.addPerm");

+		invalidate(trans, rd);

+		return rv;

+	}

+	

+	/**

+	 * Add description to this role

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param name

+	 * @param description

+	 * @return

+	 */

+	public Result<Void> addDescription(AuthzTrans trans, String ns, String name, String description) {

+		//TODO Invalidate?

+		return dao().addDescription(trans, ns, name, description);

+

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedUserRoleDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedUserRoleDAO.java
new file mode 100644
index 0000000..68231ea
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cached/CachedUserRoleDAO.java
@@ -0,0 +1,117 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cached;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO.Data;

+

+import org.onap.aaf.inno.env.Slot;

+

+public class CachedUserRoleDAO extends CachedDAO<AuthzTrans,UserRoleDAO, UserRoleDAO.Data> {

+	private Slot transURSlot;

+

+	public CachedUserRoleDAO(UserRoleDAO dao, CIDAO<AuthzTrans> info) {

+		super(dao, info, UserRoleDAO.CACHE_SEG);

+		transURSlot = dao.transURSlot;

+	}

+

+	/**

+	 * Special Case.  

+	 * User Roles by User are very likely to be called many times in a Transaction, to validate "May User do..."

+	 * Pull result, and make accessible by the Trans, which is always keyed by User.

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<List<Data>> readByUser(AuthzTrans trans, final String user) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				// If the call is for THIS user, and it exists, get from TRANS, add to TRANS if not.

+				if(user!=null && user.equals(trans.user())) {

+					Result<List<Data>> transLD = trans.get(transURSlot,null);

+					if(transLD==null ) {

+						transLD = dao.readByUser(trans, user);

+					}

+					return transLD;

+				} else {

+					return dao.readByUser(trans, user);

+				}

+			}

+		};

+		Result<List<Data>> lurd = get(trans, user, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound,"UserRole not found for [%s]",user);

+		}

+		return lurd;

+	}

+

+	

+	public Result<List<Data>> readByRole(AuthzTrans trans, final String role) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				return dao.readByRole(trans, role);

+			}

+		};

+		Result<List<Data>> lurd = get(trans, role, getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound,"UserRole not found for [%s]",role);

+		}

+		return lurd;

+	}

+

+	public Result<List<UserRoleDAO.Data>> readUserInRole(final AuthzTrans trans, final String user, final String role) {

+		DAOGetter getter = new DAOGetter(trans,dao()) {

+			public Result<List<Data>> call() {

+				if(user.equals(trans.user())) {

+					Result<List<Data>> rrbu = readByUser(trans, user);

+					if(rrbu.isOK()) {

+						List<Data> ld = new ArrayList<Data>(1);

+						for(Data d : rrbu.value) {

+							if(d.role.equals(role)) {

+								ld.add(d);

+								break;

+							}

+						}

+						return Result.ok(ld).emptyList(ld.isEmpty());

+					} else {

+						return rrbu;

+					}

+				}

+				return dao.readByUserRole(trans, user, role);

+			}

+		};

+		Result<List<Data>> lurd = get(trans, keyFromObjs(user,role), getter);

+		if(lurd.isOK() && lurd.isEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound,"UserRole not found for role [%s] and user [%s]",role,user);

+		}

+		return lurd;

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ApprovalDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ApprovalDAO.java
new file mode 100644
index 0000000..dec1c9a
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ApprovalDAO.java
@@ -0,0 +1,206 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.util.Date;

+import java.util.List;

+import java.util.UUID;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+

+public class ApprovalDAO extends CassDAOImpl<AuthzTrans,ApprovalDAO.Data> {

+	public static final String PENDING = "pending";

+	public static final String DENIED = "denied";

+	public static final String APPROVED = "approved";

+	

+	private static final String TABLE = "approval";

+	private HistoryDAO historyDAO;

+	private PSInfo psByUser, psByApprover, psByTicket, psByStatus;

+

+	

+	public ApprovalDAO(AuthzTrans trans, Cluster cluster, String keyspace) {

+		super(trans, ApprovalDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        historyDAO = new HistoryDAO(trans, this);

+		init(trans);

+	}

+

+

+	public ApprovalDAO(AuthzTrans trans, HistoryDAO hDAO) {

+		super(trans, ApprovalDAO.class.getSimpleName(),hDAO,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		historyDAO=hDAO;

+		init(trans);

+	}

+

+	private static final int KEYLIMIT = 1;

+	public static class Data {

+		public UUID   id;

+        public UUID   ticket;

+		public String user;

+		public String approver;

+		public String type;

+		public String status;

+		public String memo;

+		public String operation;

+		public Date updated;

+	}

+	

+	private static class ApprovalLoader extends Loader<Data> {

+		public static final ApprovalLoader deflt = new ApprovalLoader(KEYLIMIT);

+		

+		public ApprovalLoader(int keylimit) {

+			super(keylimit);

+		}

+		

+		@Override

+		public Data load(Data data, Row row) {

+			data.id = row.getUUID(0);

+			data.ticket = row.getUUID(1);

+			data.user = row.getString(2);

+			data.approver = row.getString(3);

+			data.type = row.getString(4);

+			data.status = row.getString(5);

+			data.memo = row.getString(6);

+			data.operation = row.getString(7);

+			if(row.getColumnDefinitions().size()>8) {

+				// Rows reported in MicroSeconds

+				data.updated = new Date(row.getLong(8)/1000);

+			}

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int idx, Object[] obj) {

+			obj[idx]=data.id;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.ticket;

+			obj[++idx]=data.user;

+			obj[++idx]=data.approver;

+			obj[++idx]=data.type;

+			obj[++idx]=data.status;

+			obj[++idx]=data.memo;

+			obj[++idx]=data.operation;

+		}

+	}	

+	

+	private void init(AuthzTrans trans) {

+		String[] helpers = setCRUD(trans, TABLE, Data.class, ApprovalLoader.deflt,8);

+		// Need a specialty Creator to handle the "now()"

+		replace(CRUD.create, new PSInfo(trans, "INSERT INTO " + TABLE + " (" +  helpers[FIELD_COMMAS] +

+					") VALUES(now(),?,?,?,?,?,?,?)",new ApprovalLoader(0) {

+						@Override

+						protected void key(Data data, int idx, Object[] obj) {

+							// Overridden because key is the "now()"

+						}

+					},writeConsistency)

+				);

+

+		psByUser = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + ", WRITETIME(status) FROM " + TABLE + 

+				" WHERE user = ?", new ApprovalLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.user;

+			}

+		}, readConsistency);

+		

+		psByApprover = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + ", WRITETIME(status) FROM " + TABLE + 

+				" WHERE approver = ?", new ApprovalLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.approver;

+			}

+		}, readConsistency);

+

+		psByTicket = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + ", WRITETIME(status) FROM " + TABLE + 

+				" WHERE ticket = ?", new ApprovalLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.ticket;

+			}

+		}, readConsistency);

+

+		psByStatus = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + ", WRITETIME(status) FROM " + TABLE + 

+				" WHERE status = ?", new ApprovalLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.status;

+			}

+		}, readConsistency);

+

+

+	}

+	

+	public Result<List<ApprovalDAO.Data>> readByUser(AuthzTrans trans, String user) {

+		return psByUser.read(trans, R_TEXT, new Object[]{user});

+	}

+

+	public Result<List<ApprovalDAO.Data>> readByApprover(AuthzTrans trans, String approver) {

+		return psByApprover.read(trans, R_TEXT, new Object[]{approver});

+	}

+

+	public Result<List<ApprovalDAO.Data>> readByTicket(AuthzTrans trans, UUID ticket) {

+		return psByTicket.read(trans, R_TEXT, new Object[]{ticket});

+	}

+

+	public Result<List<ApprovalDAO.Data>> readByStatus(AuthzTrans trans, String status) {

+		return psByStatus.read(trans, R_TEXT, new Object[]{status});

+	}	

+

+	/**

+     * Log Modification statements to History

+     *

+     * @param modified        which CRUD action was done

+     * @param data            entity data that needs a log entry

+     * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+        HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject?override[1]:data.user + "|" + data.approver;

+        hd.memo = memo

+                ? String.format("%s by %s", override[0], hd.user)

+                : (modified.name() + "d approval for " + data.user);

+        // Detail?

+        // Reconstruct?

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+    }

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ArtiDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ArtiDAO.java
new file mode 100644
index 0000000..bc5532e
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/ArtiDAO.java
@@ -0,0 +1,267 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+

+import org.onap.aaf.inno.env.util.Chrono;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+/**

+ * CredDAO manages credentials. 

+ * Date: 7/19/13

+ */

+public class ArtiDAO extends CassDAOImpl<AuthzTrans,ArtiDAO.Data> {

+    public static final String TABLE = "artifact";

+    

+    private HistoryDAO historyDAO;

+    private PSInfo psByMechID,psByMachine;

+	

+    public ArtiDAO(AuthzTrans trans, Cluster cluster, String keyspace) {

+        super(trans, ArtiDAO.class.getSimpleName(),cluster, keyspace, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        init(trans);

+    }

+

+    public ArtiDAO(AuthzTrans trans, HistoryDAO hDao, CacheInfoDAO ciDao) {

+        super(trans, ArtiDAO.class.getSimpleName(),hDao, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        historyDAO = hDao;

+        init(trans);

+    }

+

+    public static final int KEYLIMIT = 2;

+	public static class Data implements Bytification {

+		public String       			mechid;

+		public String       			machine;

+        private Set<String>      		type;

+        public String					sponsor;

+        public String					ca;

+        public String					dir;

+        public String					appName;

+        public String					os_user;

+        public String					notify;

+        public Date      				expires;

+        public int						renewDays;

+        

+//      // Getters

+		public Set<String> type(boolean mutable) {

+			if (type == null) {

+				type = new HashSet<String>();

+			} else if (mutable && !(type instanceof HashSet)) {

+				type = new HashSet<String>(type);

+			}

+			return type;

+		}

+

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			ArtifactLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			ArtifactLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+

+		public String toString() {

+			return mechid + ' ' + machine + ' ' + Chrono.dateTime(expires);

+		}

+    }

+

+    private static class ArtifactLoader extends Loader<Data> implements Streamer<Data>{

+		public static final int MAGIC=95829343;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48; // Note: 

+

+    	public static final ArtifactLoader deflt = new ArtifactLoader(KEYLIMIT);

+    	public ArtifactLoader(int keylimit) {

+            super(keylimit);

+        }

+

+    	@Override

+        public Data load(Data data, Row row) {

+            data.mechid = row.getString(0);

+            data.machine = row.getString(1);

+            data.type = row.getSet(2, String.class);

+            data.sponsor = row.getString(3);

+            data.ca = row.getString(4);

+            data.dir = row.getString(5);

+            data.appName = row.getString(6);

+            data.os_user = row.getString(7);

+            data.notify = row.getString(8);

+            data.expires = row.getDate(9);

+            data.renewDays = row.getInt(10);

+            return data;

+        }

+

+        @Override

+        protected void key(final Data data, final int idx, Object[] obj) {

+        	int i;

+            obj[i=idx] = data.mechid;

+            obj[++i] = data.machine;

+        }

+

+        @Override

+        protected void body(final Data data, final int idx, Object[] obj) {

+            int i;

+            obj[i=idx] = data.type;

+            obj[++i] = data.sponsor;

+            obj[++i] = data.ca;

+            obj[++i] = data.dir;

+            obj[++i] = data.appName;

+            obj[++i] = data.os_user;

+            obj[++i] = data.notify;

+            obj[++i] = data.expires;

+            obj[++i] = data.renewDays;

+        }

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.mechid);

+			writeString(os, data.machine);

+			os.writeInt(data.type.size());

+			for(String s : data.type) {

+				writeString(os, s);

+			}

+			writeString(os, data.sponsor);

+			writeString(os, data.ca);

+			writeString(os, data.dir);

+			writeString(os, data.appName);

+			writeString(os, data.os_user);

+			writeString(os, data.notify);

+			os.writeLong(data.expires==null?-1:data.expires.getTime());

+			os.writeInt(data.renewDays);

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.mechid = readString(is,buff);

+			data.machine = readString(is,buff);

+			int size = is.readInt();

+			data.type = new HashSet<String>(size);

+			for(int i=0;i<size;++i) {

+				data.type.add(readString(is,buff));

+			}

+			data.sponsor = readString(is,buff);

+			data.ca = readString(is,buff);

+			data.dir = readString(is,buff);

+			data.appName = readString(is,buff);

+			data.os_user = readString(is,buff);

+			data.notify = readString(is,buff);

+			long l = is.readLong();

+			data.expires = l<0?null:new Date(l);

+			data.renewDays = is.readInt();

+		}

+    }

+

+    private void init(AuthzTrans trans) {

+        // Set up sub-DAOs

+        if(historyDAO==null) {

+        	historyDAO = new HistoryDAO(trans,this);

+        }

+        

+        String[] helpers = setCRUD(trans, TABLE, Data.class, ArtifactLoader.deflt);

+

+		psByMechID = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE + 

+				" WHERE mechid = ?", new ArtifactLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.type;

+			}

+		},readConsistency);

+

+		psByMachine = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE + 

+				" WHERE machine = ?", new ArtifactLoader(1) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.type;

+			}

+		},readConsistency);

+

+    }

+    

+	

+    public Result<List<Data>> readByMechID(AuthzTrans trans, String mechid) {

+		return psByMechID.read(trans, R_TEXT, new Object[]{mechid});

+	}

+

+	public Result<List<ArtiDAO.Data>> readByMachine(AuthzTrans trans, String machine) {

+		return psByMachine.read(trans, R_TEXT, new Object[]{machine});

+	}

+

+	/**

+     * Log Modification statements to History

+     *

+     * @param modified        which CRUD action was done

+     * @param data            entity data that needs a log entry

+     * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+        HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject?override[1]: data.mechid;

+        hd.memo = memo

+                ? String.format("%s by %s", override[0], hd.user)

+                : String.format("%sd %s for %s",modified.name(),data.mechid,data.machine);

+        // Detail?

+   		if(modified==CRUD.delete) {

+        			try {

+        				hd.reconstruct = data.bytify();

+        			} catch (IOException e) {

+        				trans.error().log(e,"Could not serialize CredDAO.Data");

+        			}

+        		}

+

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+    }

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheInfoDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheInfoDAO.java
new file mode 100644
index 0000000..e7cab3e
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheInfoDAO.java
@@ -0,0 +1,464 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.IOException;

+import java.net.HttpURLConnection;

+import java.net.URI;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.concurrent.BlockingQueue;

+import java.util.concurrent.ConcurrentHashMap;

+import java.util.concurrent.LinkedBlockingQueue;

+import java.util.concurrent.TimeUnit;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.AbsCassDAO;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.SecuritySetter;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.http.HMangr;

+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.Trans;

+import com.datastax.driver.core.BoundStatement;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.exceptions.DriverException;

+

+public class CacheInfoDAO extends CassDAOImpl<AuthzTrans,CacheInfoDAO.Data> implements CIDAO<AuthzTrans> {

+

+	private static final String TABLE = "cache";

+	public static final Map<String,Date[]> info = new ConcurrentHashMap<String,Date[]>();

+

+	private static CacheUpdate cacheUpdate;

+	

+	

+	private BoundStatement check;

+	// Hold current time stamps from Tables

+	private final Date startTime;

+	

+	public CacheInfoDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+		super(trans, CacheInfoDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE,readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		startTime = new Date();

+		init(trans);

+	}

+

+	public CacheInfoDAO(AuthzTrans trans, AbsCassDAO<AuthzTrans,?> aDao) throws APIException, IOException {

+		super(trans, CacheInfoDAO.class.getSimpleName(),aDao,Data.class,TABLE,readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		startTime = new Date();

+		init(trans);

+	}

+

+

+    //////////////////////////////////////////

+    // Data Definition, matches Cassandra DM

+    //////////////////////////////////////////

+    private static final int KEYLIMIT = 2;

+	/**

+     */

+	public static class Data {

+		public Data() {

+			name = null;

+			touched = null;

+		}

+		public Data(String name, int seg) {

+			this.name = name;

+			this.seg = seg;

+			touched = null;

+		}

+		

+		public String		name;

+		public int			seg;

+		public Date			touched;

+    }

+

+    private static class InfoLoader extends Loader<Data> {

+    	public static final InfoLoader dflt = new InfoLoader(KEYLIMIT);

+    	

+		public InfoLoader(int keylimit) {

+			super(keylimit);

+		}

+		

+		@Override

+		public Data load(Data data, Row row) {

+			// Int more efficient

+			data.name = row.getString(0);

+			data.seg = row.getInt(1);

+			data.touched = row.getDate(2);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+

+			obj[idx]=data.name;

+			obj[++idx]=data.seg;

+		}

+

+		@Override

+		protected void body(Data data, int idx, Object[] obj) {

+			obj[idx]=data.touched;

+		}

+    }

+    

+	public static<T extends Trans> void startUpdate(AuthzEnv env, HMangr hman, SecuritySetter<HttpURLConnection> ss, String ip, int port) {

+		if(cacheUpdate==null) {

+			Thread t= new Thread(cacheUpdate = new CacheUpdate(env,hman,ss, ip,port),"CacheInfo Update Thread");

+			t.setDaemon(true);

+			t.start();

+		}

+	}

+

+	public static<T extends Trans> void stopUpdate() {

+		if(cacheUpdate!=null) {

+			cacheUpdate.go=false;

+		}

+	}

+

+	private final static class CacheUpdate extends Thread {

+		public static BlockingQueue<Transfer> notifyDQ = new LinkedBlockingQueue<Transfer>(2000);

+

+		private static final String VOID_CT="application/Void+json;q=1.0;charset=utf-8;version=2.0,application/json;q=1.0;version=2.0,*/*;q=1.0";

+		private AuthzEnv env;

+		private HMangr hman;

+		private SecuritySetter<HttpURLConnection> ss;

+		private final String authority;

+		public boolean go = true;

+		

+		public CacheUpdate(AuthzEnv env, HMangr hman, SecuritySetter<HttpURLConnection> ss, String ip, int port) {

+			this.env = env;

+			this.hman = hman;

+			this.ss = ss;

+			

+			this.authority = ip+':'+port;

+		}

+		

+		private static class Transfer {

+			public String table;

+			public int segs[];

+			public Transfer(String table, int[] segs)  {

+				this.table = table;

+				this.segs = segs;

+			}

+		}

+		private class CacheClear extends Retryable<Integer> {

+			public int total=0;

+			private AuthzTrans trans;

+			private String type;

+			private String segs;

+			

+			public CacheClear(AuthzTrans trans) {

+				this.trans = trans;

+			}

+

+			public void set(Entry<String, IntHolder> es) {

+				type = es.getKey();

+				segs = es.getValue().toString();

+			}

+			

+		@Override

+			public Integer code(Rcli<?> client) throws APIException, CadiException {

+				URI to = client.getURI();

+				if(!to.getAuthority().equals(authority)) {

+					Future<Void> f = client.delete("/mgmt/cache/"+type+'/'+segs,VOID_CT);

+					if(f.get(hman.readTimeout())) {

+					    ++total;

+					} else {

+					    trans.error().log("Error During AAF Peer Notify",f.code(),f.body());

+					}

+				}

+				return total;

+			}

+		}

+		

+		private class IntHolder {

+			private int[] raw;

+			HashSet<Integer> set;

+			

+			public IntHolder(int ints[]) {

+				raw = ints;

+				set = null;

+			}

+			public void add(int[] ints) {

+				if(set==null) {

+					set = new HashSet<Integer>();

+					

+					for(int i=0;i<raw.length;++i) {

+						set.add(raw[i]);

+					}

+				}

+				for(int i=0;i<ints.length;++i) {

+					set.add(ints[i]);

+				}

+			}

+

+			@Override

+			public String toString() {

+				StringBuilder sb = new StringBuilder();

+				boolean first = true;

+				if(set==null) {

+					for(int i : raw) {

+						if(first) {

+							first=false;

+						} else {

+							sb.append(',');

+						}

+						sb.append(i);

+					}

+				} else {

+					for(Integer i : set) {

+						if(first) {

+							first=false;

+						} else {

+							sb.append(',');

+						}

+						sb.append(i);

+					}

+				}

+				return sb.toString();

+			}

+		}

+		

+		@Override

+		public void run() {

+			do {

+				try {

+					Transfer data = notifyDQ.poll(4,TimeUnit.SECONDS);

+					if(data==null) {

+						continue;

+					}

+					

+					int count = 0;

+					CacheClear cc = null;

+					Map<String,IntHolder> gather = null;

+					AuthzTrans trans = null;

+					long start=0;

+					// Do a block poll first

+					do {

+						if(gather==null) {

+							start = System.nanoTime();

+							trans = env.newTransNoAvg();

+							cc = new CacheClear(trans);

+							gather = new HashMap<String,IntHolder>();

+						}

+						IntHolder prev = gather.get(data.table);

+						if(prev==null) {

+							gather.put(data.table,new IntHolder(data.segs));

+						} else {

+							prev.add(data.segs);

+						}

+						// continue while there is data

+					} while((data = notifyDQ.poll())!=null);

+					if(gather!=null) {

+						for(Entry<String, IntHolder> es : gather.entrySet()) {

+							cc.set(es);

+							try {

+								if(hman.all(ss, cc, false)!=null) {

+									++count;

+								}

+							} catch (Exception e) {

+								trans.error().log(e, "Error on Cache Update");

+							}

+						}

+						if(env.debug().isLoggable()) {

+							float millis = (System.nanoTime()-start)/1000000f;

+							StringBuilder sb = new StringBuilder("Direct Cache Refresh: ");

+							sb.append("Updated ");

+							sb.append(count);

+							if(count==1) {

+								sb.append(" entry for ");

+							} else { 

+								sb.append(" entries for ");

+							}

+							int peers = count<=0?0:cc.total/count;

+							sb.append(peers);

+							sb.append(" client");

+							if(peers!=1) {

+								sb.append('s');

+							}

+							sb.append(" in ");

+							sb.append(millis);

+							sb.append("ms");

+							trans.auditTrail(0, sb, Env.REMOTE);

+							env.debug().log(sb);

+						}

+					}

+				} catch (InterruptedException e1) {

+					go = false;

+				}

+			} while(go);

+		}

+	}

+

+	private void init(AuthzTrans trans) throws APIException, IOException {

+		

+		String[] helpers = setCRUD(trans, TABLE, Data.class, InfoLoader.dflt);

+		check = getSession(trans).prepare(SELECT_SP +  helpers[FIELD_COMMAS] + " FROM " + TABLE).bind();

+

+		disable(CRUD.create);

+		disable(CRUD.delete);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.dao.aaf.cass.CIDAO#touch(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, int)

+	 */

+	

+	@Override

+	public Result<Void> touch(AuthzTrans trans, String name, int ... seg) {

+		/////////////

+		// Direct Service Cache Invalidation

+		/////////////

+		// ConcurrentQueues are open-ended.  We don't want any Memory leaks 

+		// Note: we keep a separate counter, because "size()" on a Linked Queue is expensive

+		if(cacheUpdate!=null) {

+			try {

+				if(!CacheUpdate.notifyDQ.offer(new CacheUpdate.Transfer(name, seg),2,TimeUnit.SECONDS)) {

+					trans.error().log("Cache Notify Queue is not accepting messages, bouncing may be appropriate" );

+				}

+			} catch (InterruptedException e) {

+				trans.error().log("Cache Notify Queue posting was interrupted" );

+			}

+		}

+

+		/////////////

+		// Table Based Cache Invalidation (original)

+		/////////////

+		// Note: Save time with multiple Sequence Touches, but PreparedStmt doesn't support IN

+		StringBuilder start = new StringBuilder("CacheInfoDAO Touch segments ");

+		start.append(name);

+		start.append(": ");

+		StringBuilder sb = new StringBuilder("BEGIN BATCH\n");

+		boolean first = true;

+		for(int s : seg) {

+			sb.append(UPDATE_SP);

+			sb.append(TABLE);

+			sb.append(" SET touched=dateof(now()) WHERE name = '");

+			sb.append(name);

+			sb.append("' AND seg = ");

+			sb.append(s);

+			sb.append(";\n");	

+			if(first) {

+				first =false;

+			} else {

+				start.append(',');

+			}

+			start.append(s);

+		}

+		sb.append("APPLY BATCH;");

+		TimeTaken tt = trans.start(start.toString(),Env.REMOTE);

+		try {

+			getSession(trans).executeAsync(sb.toString());

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		} finally {

+			tt.done();

+		}

+		return Result.ok();

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.dao.aaf.cass.CIDAO#check(org.onap.aaf.authz.env.AuthzTrans)

+	 */

+	@Override

+	public Result<Void> check(AuthzTrans trans) {

+		ResultSet rs;

+		TimeTaken tt = trans.start("Check Table Timestamps",Env.REMOTE);

+		try {

+			rs = getSession(trans).execute(check);

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		} finally {

+			tt.done();

+		}

+		

+		String lastName = null;

+		Date[] dates = null;

+		for(Row row : rs.all()) {

+			String name = row.getString(0);

+			int seg = row.getInt(1);

+			if(!name.equals(lastName)) {

+				dates = info.get(name);

+				lastName=name;

+			}

+			if(dates==null) {

+				dates=new Date[seg+1];

+				info.put(name,dates);

+			} else if(dates.length<=seg) {

+				Date[] temp = new Date[seg+1];

+				System.arraycopy(dates, 0, temp, 0, dates.length);

+				dates = temp;

+				info.put(name, dates);

+			}

+			Date temp = row.getDate(2);

+			if(dates[seg]==null || dates[seg].before(temp)) {

+				dates[seg]=temp;

+			}

+		}

+		return Result.ok();

+	}

+	

+    /* (non-Javadoc)

+	 * @see org.onap.aaf.dao.aaf.cass.CIDAO#get(java.lang.String, int)

+	 */

+    @Override

+	public Date get(AuthzTrans trans, String table, int seg) {

+		Date[] dates = info.get(table);

+		if(dates==null) {

+			dates = new Date[seg+1];

+			touch(trans,table, seg);

+		} else if(dates.length<=seg) {

+			Date[] temp = new Date[seg+1];

+			System.arraycopy(dates, 0, temp, 0, dates.length);

+			dates = temp;

+		}

+		Date rv = dates[seg];

+		if(rv==null) {

+			rv=dates[seg]=startTime;

+		}

+		return rv;

+	}

+

+	@Override

+	protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+		// Do nothing

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheableData.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheableData.java
new file mode 100644
index 0000000..7564813
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CacheableData.java
@@ -0,0 +1,36 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import org.onap.aaf.dao.Cacheable;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CachedDAO;

+

+public abstract class CacheableData implements Cacheable {

+	// WARNING:  DON'T attempt to add any members here, as it will 

+	// be treated by system as fields expected in Tables

+	protected int seg(Cached<?,?> cache, Object ... fields) {

+		return cache==null?0:cache.invalidate(CachedDAO.keyFromObjs(fields));

+	}

+	

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CertDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CertDAO.java
new file mode 100644
index 0000000..4ed6a3e
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CertDAO.java
@@ -0,0 +1,244 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.math.BigInteger;

+import java.nio.ByteBuffer;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+

+import org.onap.aaf.inno.env.APIException;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+/**

+ * CredDAO manages credentials. 

+ * Date: 7/19/13

+ */

+public class CertDAO extends CassDAOImpl<AuthzTrans,CertDAO.Data> {

+    public static final String TABLE = "x509";

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+    

+    private HistoryDAO historyDAO;

+	private CIDAO<AuthzTrans> infoDAO;

+	private PSInfo psX500,psID;

+	

+    public CertDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+        super(trans, CertDAO.class.getSimpleName(),cluster, keyspace, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        init(trans);

+    }

+

+    public CertDAO(AuthzTrans trans, HistoryDAO hDao, CacheInfoDAO ciDao) throws APIException, IOException {

+        super(trans, CertDAO.class.getSimpleName(),hDao, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        historyDAO = hDao;

+        infoDAO = ciDao;

+        init(trans);

+    }

+    

+    public static final int KEYLIMIT = 2;

+	public static class Data extends CacheableData implements Bytification {

+    	

+        public String					ca;

+		public BigInteger 				serial;

+        public String	      			id;

+        public String					x500;

+        public String					x509;

+

+        @Override

+		public int[] invalidate(Cached<?,?> cache) {

+        	return new int[] {

+        		seg(cache,ca,serial)

+        	};

+		}

+        

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			CertLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			CertLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+    }

+

+    private static class CertLoader extends Loader<Data> implements Streamer<Data>{

+		public static final int MAGIC=85102934;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48; // Note: 

+

+    	public static final CertLoader deflt = new CertLoader(KEYLIMIT);

+    	public CertLoader(int keylimit) {

+            super(keylimit);

+        }

+

+    	@Override

+        public Data load(Data data, Row row) {

+        	data.ca = row.getString(0);

+            ByteBuffer bb = row.getBytesUnsafe(1);

+            byte[] bytes = new byte[bb.remaining()];

+            bb.get(bytes);

+            data.serial = new BigInteger(bytes);

+            data.id = row.getString(2);

+            data.x500 = row.getString(3);

+            data.x509 = row.getString(4);

+            return data;

+        }

+

+        @Override

+        protected void key(Data data, int idx, Object[] obj) {

+            obj[idx] = data.ca;

+            obj[++idx] = ByteBuffer.wrap(data.serial.toByteArray());

+        }

+

+        @Override

+        protected void body(Data data, int _idx, Object[] obj) {

+        	int idx = _idx;

+

+            obj[idx] = data.id;

+            obj[++idx] = data.x500;

+            obj[++idx] = data.x509;

+

+            

+        }

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.id);

+			writeString(os, data.x500);

+			writeString(os, data.x509);

+			writeString(os, data.ca);

+			if(data.serial==null) {

+				os.writeInt(-1);

+			} else {

+				byte[] dsba = data.serial.toByteArray();

+				int l = dsba.length;

+				os.writeInt(l);

+				os.write(dsba,0,l);

+			}

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.id = readString(is,buff);

+			data.x500 = readString(is,buff);

+			data.x509 = readString(is,buff);

+			data.ca = readString(is,buff);

+			int i = is.readInt();

+			if(i<0) {

+				data.serial=null;

+			} else {

+				byte[] bytes = new byte[i]; // a bit dangerous, but lessened because of all the previous sized data reads

+				is.read(bytes);

+				data.serial = new BigInteger(bytes);

+			}

+		}

+    }

+    

+    public Result<List<CertDAO.Data>> read(AuthzTrans trans, Object ... key) {

+    	// Translate BigInteger to Byte array for lookup

+    	return super.read(trans, key[0],ByteBuffer.wrap(((BigInteger)key[1]).toByteArray()));

+    }

+

+    private void init(AuthzTrans trans) throws APIException, IOException {

+        // Set up sub-DAOs

+        if(historyDAO==null) {

+        	historyDAO = new HistoryDAO(trans,this);

+        }

+		if(infoDAO==null) {

+			infoDAO = new CacheInfoDAO(trans,this);

+		}

+

+		String[] helpers = setCRUD(trans, TABLE, Data.class, CertLoader.deflt);

+

+		psID = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE id = ?", CertLoader.deflt,readConsistency);

+

+		psX500 = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE x500 = ?", CertLoader.deflt,readConsistency);

+		

+    }

+    

+	public Result<List<Data>> readX500(AuthzTrans trans, String x500) {

+		return psX500.read(trans, R_TEXT, new Object[]{x500});

+	}

+

+	public Result<List<Data>> readID(AuthzTrans trans, String id) {

+		return psID.read(trans, R_TEXT, new Object[]{id});

+	}

+

+    /**

+     * Log Modification statements to History

+     *

+     * @param modified        which CRUD action was done

+     * @param data            entity data that needs a log entry

+     * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+        HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject?override[1]: data.id;

+        hd.memo = memo

+                ? String.format("%s by %s", override[0], hd.user)

+                : (modified.name() + "d certificate info for " + data.id);

+        // Detail?

+   		if(modified==CRUD.delete) {

+        			try {

+        				hd.reconstruct = data.bytify();

+        			} catch (IOException e) {

+        				trans.error().log(e,"Could not serialize CertDAO.Data");

+        			}

+        		}

+

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).status!=Status.OK) {

+        	trans.error().log("Cannot touch Cert");

+        }

+    }

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CredDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CredDAO.java
new file mode 100644
index 0000000..dad5fdb
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/CredDAO.java
@@ -0,0 +1,258 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Chrono;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+/**

+ * CredDAO manages credentials. 

+ * Date: 7/19/13

+ */

+public class CredDAO extends CassDAOImpl<AuthzTrans,CredDAO.Data> {

+    public static final String TABLE = "cred";

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+	public static final int RAW = -1;

+    public static final int BASIC_AUTH = 1;

+    public static final int BASIC_AUTH_SHA256 = 2;

+    public static final int CERT_SHA256_RSA =200;

+    

+    private HistoryDAO historyDAO;

+	private CIDAO<AuthzTrans> infoDAO;

+	private PSInfo psNS;

+	private PSInfo psID;

+	

+    public CredDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+        super(trans, CredDAO.class.getSimpleName(),cluster, keyspace, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        init(trans);

+    }

+

+    public CredDAO(AuthzTrans trans, HistoryDAO hDao, CacheInfoDAO ciDao) throws APIException, IOException {

+        super(trans, CredDAO.class.getSimpleName(),hDao, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        historyDAO = hDao;

+        infoDAO = ciDao;

+        init(trans);

+    }

+

+    public static final int KEYLIMIT = 3;

+	public static class Data extends CacheableData implements Bytification {

+    	

+		public String       			id;

+        public Integer      			type;

+        public Date      				expires;

+        public Integer					other;

+		public String					ns;

+		public String					notes;

+        public ByteBuffer				cred;  //   this is a blob in cassandra

+

+

+        @Override

+		public int[] invalidate(Cached<?,?> cache) {

+        	return new int[] {

+        		seg(cache,id) // cache is for all entities

+        	};

+		}

+        

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			CredLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			CredLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+

+		public String toString() {

+			return id + ' ' + type + ' ' + Chrono.dateTime(expires);

+		}

+    }

+

+    private static class CredLoader extends Loader<Data> implements Streamer<Data>{

+		public static final int MAGIC=153323443;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48; // Note: 

+

+    	public static final CredLoader deflt = new CredLoader(KEYLIMIT);

+    	public CredLoader(int keylimit) {

+            super(keylimit);

+        }

+

+    	@Override

+        public Data load(Data data, Row row) {

+            data.id = row.getString(0);

+            data.type = row.getInt(1);    // NOTE: in datastax driver,  If the int value is NULL, 0 is returned!

+            data.expires = row.getDate(2);

+            data.other = row.getInt(3);

+            data.ns = row.getString(4);     

+            data.notes = row.getString(5);

+            data.cred = row.getBytesUnsafe(6);            

+            return data;

+        }

+

+        @Override

+        protected void key(Data data, int _idx, Object[] obj) {

+	    int idx = _idx;

+

+            obj[idx] = data.id;

+            obj[++idx] = data.type;

+            obj[++idx] = data.expires;

+        }

+

+        @Override

+        protected void body(Data data, int idx, Object[] obj) {

+            int i;

+            obj[i=idx] = data.other;

+            obj[++i] = data.ns;

+            obj[++i] = data.notes;

+            obj[++i] = data.cred;

+        }

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.id);

+			os.writeInt(data.type);	

+			os.writeLong(data.expires==null?-1:data.expires.getTime());

+			os.writeInt(data.other==null?0:data.other);

+			writeString(os, data.ns);

+			writeString(os, data.notes);

+			if(data.cred==null) {

+				os.writeInt(-1);

+			} else {

+				int l = data.cred.limit()-data.cred.position();

+				os.writeInt(l);

+				os.write(data.cred.array(),data.cred.position(),l);

+			}

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.id = readString(is,buff);

+			data.type = is.readInt();

+			

+			long l = is.readLong();

+			data.expires = l<0?null:new Date(l);

+			data.other = is.readInt();

+			data.ns = readString(is,buff);

+			data.notes = readString(is,buff);

+			

+			int i = is.readInt();

+			if(i<0) {

+				data.cred=null;

+			} else {

+				byte[] bytes = new byte[i]; // a bit dangerous, but lessened because of all the previous sized data reads

+				is.read(bytes);

+				data.cred = ByteBuffer.wrap(bytes);

+			}

+		}

+    }

+

+    private void init(AuthzTrans trans) throws APIException, IOException {

+        // Set up sub-DAOs

+        if(historyDAO==null) {

+        	historyDAO = new HistoryDAO(trans,this);

+        }

+		if(infoDAO==null) {

+			infoDAO = new CacheInfoDAO(trans,this);

+		}

+		

+

+		String[] helpers = setCRUD(trans, TABLE, Data.class, CredLoader.deflt);

+		

+		psNS = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE ns = ?", CredLoader.deflt,readConsistency);

+		

+		psID = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE id = ?", CredLoader.deflt,readConsistency);

+    }

+    

+	public Result<List<Data>> readNS(AuthzTrans trans, String ns) {

+		return psNS.read(trans, R_TEXT, new Object[]{ns});

+	}

+	

+	public Result<List<Data>> readID(AuthzTrans trans, String id) {

+		return psID.read(trans, R_TEXT, new Object[]{id});

+	}

+	

+    /**

+     * Log Modification statements to History

+     *

+     * @param modified        which CRUD action was done

+     * @param data            entity data that needs a log entry

+     * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+        HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject?override[1]: data.id;

+        hd.memo = memo

+                ? String.format("%s by %s", override[0], hd.user)

+                : (modified.name() + "d credential for " + data.id);

+        // Detail?

+   		if(modified==CRUD.delete) {

+        			try {

+        				hd.reconstruct = data.bytify();

+        			} catch (IOException e) {

+        				trans.error().log(e,"Could not serialize CredDAO.Data");

+        			}

+        		}

+

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).status!=Status.OK) {

+        	trans.error().log("Cannot touch Cred");

+        }

+    }

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/DelegateDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/DelegateDAO.java
new file mode 100644
index 0000000..6ff7120
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/DelegateDAO.java
@@ -0,0 +1,139 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.AbsCassDAO;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+public class DelegateDAO extends CassDAOImpl<AuthzTrans, DelegateDAO.Data> {

+

+	public static final String TABLE = "delegate";

+	private PSInfo psByDelegate;

+	

+	public DelegateDAO(AuthzTrans trans, Cluster cluster, String keyspace) {

+		super(trans, DelegateDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		init(trans);

+	}

+

+	public DelegateDAO(AuthzTrans trans, AbsCassDAO<AuthzTrans,?> aDao) {

+		super(trans, DelegateDAO.class.getSimpleName(),aDao,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		init(trans);

+	}

+	

+	private static final int KEYLIMIT = 1;

+	public static class Data implements Bytification {

+		public String user;

+		public String delegate;

+		public Date expires;

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			DelegateLoader.dflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			DelegateLoader.dflt.unmarshal(this, toDIS(bb));

+		}

+	}

+	

+	private static class DelegateLoader extends Loader<Data> implements Streamer<Data>{

+		public static final int MAGIC=0xD823ACF2;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48;

+

+		public static final DelegateLoader dflt = new DelegateLoader(KEYLIMIT);

+

+		public DelegateLoader(int keylimit) {

+			super(keylimit);

+		}

+		

+		@Override

+		public Data load(Data data, Row row) {

+			data.user = row.getString(0);

+			data.delegate = row.getString(1);

+			data.expires = row.getDate(2);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int idx, Object[] obj) {

+			obj[idx]=data.user;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+

+			obj[idx]=data.delegate;

+			obj[++idx]=data.expires;

+		}

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.user);

+			writeString(os, data.delegate);

+			os.writeLong(data.expires.getTime());

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.user = readString(is, buff);

+			data.delegate = readString(is,buff);

+			data.expires = new Date(is.readLong());

+		}

+	}	

+	

+	private void init(AuthzTrans trans) {

+		String[] helpers = setCRUD(trans, TABLE, Data.class, DelegateLoader.dflt);

+		psByDelegate = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE delegate = ?", new DelegateLoader(1),readConsistency);

+

+	}

+

+	public Result<List<DelegateDAO.Data>> readByDelegate(AuthzTrans trans, String delegate) {

+		return psByDelegate.read(trans, R_TEXT, new Object[]{delegate});

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/FutureDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/FutureDAO.java
new file mode 100644
index 0000000..4fda97a
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/FutureDAO.java
@@ -0,0 +1,183 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.List;

+import java.util.UUID;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.Loader;

+

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.Row;

+

+/**

+ * FutureDAO stores Construction information to create 

+ * elements at another time.

+ * 

+ * 8/20/2013

+ */

+public class FutureDAO extends CassDAOImpl<AuthzTrans,FutureDAO.Data> {

+    private static final String TABLE = "future";

+	private final HistoryDAO historyDAO;

+//	private static String createString;

+	private PSInfo psByStartAndTarget;

+	

+    public FutureDAO(AuthzTrans trans, Cluster cluster, String keyspace) {

+        super(trans, FutureDAO.class.getSimpleName(),cluster, keyspace, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		historyDAO = new HistoryDAO(trans, this);

+        init(trans);

+    }

+

+    public FutureDAO(AuthzTrans trans, HistoryDAO hDAO) {

+        super(trans, FutureDAO.class.getSimpleName(),hDAO, Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        historyDAO=hDAO;

+        init(trans);

+    }

+

+    public static final int KEYLIMIT = 1;

+    public static class Data {

+        public UUID         id;

+        public String		target;

+        public String		memo;

+        public Date       	start;

+        public Date       	expires;

+        public ByteBuffer 	construct;  //   this is a blob in cassandra

+    }

+

+    private static class FLoader extends Loader<Data> {

+        public FLoader() {

+            super(KEYLIMIT);

+        }

+

+        public FLoader(int keylimit) {

+            super(keylimit);

+        }

+

+        @Override

+	public Data load(Data data, Row row) {

+            data.id 		= row.getUUID(0);

+            data.target		= row.getString(1);

+            data.memo       = row.getString(2);

+            data.start 		= row.getDate(3);

+            data.expires 	= row.getDate(4);

+            data.construct 	= row.getBytes(5);

+            return data;

+        }

+

+        @Override

+        protected void key(Data data, int idx, Object[] obj) {

+            obj[idx] = data.id;

+        }

+

+        @Override

+        protected void body(Data data, int _idx, Object[] obj) {

+	    int idx = _idx;

+

+            obj[idx] = data.target;

+            obj[++idx] = data.memo;

+            obj[++idx] = data.start;

+            obj[++idx] = data.expires;

+            obj[++idx] = data.construct;

+        }

+    }

+

+    private void init(AuthzTrans trans) {

+        // Set up sub-DAOs

+        String[] helpers = setCRUD(trans, TABLE, Data.class, new FLoader(KEYLIMIT));

+

+        // Uh, oh.  Can't use "now()" in Prepared Statements (at least at this level)

+//		createString = "INSERT INTO " + TABLE + " ("+helpers[FIELD_COMMAS] +") VALUES (now(),";

+//

+//		// Need a specialty Creator to handle the "now()"

+//		replace(CRUD.Create, new PSInfo(trans, "INSERT INTO future (" +  helpers[FIELD_COMMAS] +

+//					") VALUES(now(),?,?,?,?,?)",new FLoader(0)));

+		

+		// Other SELECT style statements... match with a local Method

+		psByStartAndTarget = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] +

+				" FROM future WHERE start <= ? and target = ? ALLOW FILTERING", new FLoader(2) {

+			@Override

+			protected void key(Data data, int _idx, Object[] obj) {

+			    	int idx = _idx;

+

+				obj[idx]=data.start;

+				obj[++idx]=data.target;

+			}

+		},readConsistency);

+		

+

+    }

+

+    public Result<List<Data>> readByStartAndTarget(AuthzTrans trans, Date start, String target) throws DAOException {

+		return psByStartAndTarget.read(trans, R_TEXT, new Object[]{start, target});

+	}

+

+    /**

+	 * Override create to add secondary ID to Subject in History, and create Data.ID, if it is null

+     */

+	public Result<FutureDAO.Data> create(AuthzTrans trans,	FutureDAO.Data data, String id) {

+		// If ID is not set (typical), create one.

+		if(data.id==null) {

+			StringBuilder sb = new StringBuilder(trans.user());

+			sb.append(data.target);

+			sb.append(System.currentTimeMillis());

+			data.id = UUID.nameUUIDFromBytes(sb.toString().getBytes());

+		}

+		Result<ResultSet> rs = createPS.exec(trans, C_TEXT, data);

+		if(rs.notOK()) {

+			return Result.err(rs);

+		}

+		wasModified(trans, CRUD.create, data, null, id);

+		return Result.ok(data);	

+	}

+

+	/**

+	 * Log Modification statements to History

+	 *

+	 * @param modified        which CRUD action was done

+	 * @param data            entity data that needs a log entry

+	 * @param overrideMessage if this is specified, we use it rather than crafting a history message based on data

+	 */

+	@Override

+	protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+		boolean memo = override.length>0 && override[0]!=null;

+		boolean subject = override.length>1 && override[1]!=null;

+		HistoryDAO.Data hd = HistoryDAO.newInitedData();

+	    hd.user = trans.user();

+		hd.action = modified.name();

+		hd.target = TABLE;

+		hd.subject = subject?override[1]:"";

+	    hd.memo = memo?String.format("%s by %s", override[0], hd.user):data.memo;

+	

+		if(historyDAO.create(trans, hd).status!=Status.OK) {

+	    	trans.error().log("Cannot log to History");

+		}

+	}

+    

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/HistoryDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/HistoryDAO.java
new file mode 100644
index 0000000..e72c774
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/HistoryDAO.java
@@ -0,0 +1,237 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.nio.ByteBuffer;

+import java.text.SimpleDateFormat;

+import java.util.Date;

+import java.util.List;

+import java.util.UUID;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.AbsCassDAO;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ConsistencyLevel;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.Row;

+

+/**

+ * History

+ * 

+ * 

+ * History is a special case, because we don't want Updates or Deletes...  Too likely to mess up history.

+ * 

+ * 9-9-2013 - Found a problem with using "Prepare".  You cannot prepare anything with a "now()" in it, as

+ * it is evaluated once during the prepare, and kept.  That renders any use of "now()" pointless.  Therefore

+ * the Create function needs to be run fresh everytime.

+ * 

+ * Fixed in Cassandra 1.2.6 https://issues.apache.org/jira/browse/CASSANDRA-5616

+ *

+ */

+public class HistoryDAO extends CassDAOImpl<AuthzTrans, HistoryDAO.Data> {

+	private static final String TABLE = "history";

+

+	public static final SimpleDateFormat monthFormat = new SimpleDateFormat("yyyyMM");

+//	private static final SimpleDateFormat dayTimeFormat = new SimpleDateFormat("ddHHmmss");

+

+	private String[] helpers;

+

+	private HistLoader defLoader;

+

+	private AbsCassDAO<AuthzTrans, Data>.PSInfo readByUser, readBySubject, readByYRMN;

+

+	public HistoryDAO(AuthzTrans trans, Cluster cluster, String keyspace) {

+		super(trans, HistoryDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE,ConsistencyLevel.LOCAL_ONE,ConsistencyLevel.ANY);

+		init(trans);

+	}

+

+	public HistoryDAO(AuthzTrans trans, AbsCassDAO<AuthzTrans,?> aDao) {

+		super(trans, HistoryDAO.class.getSimpleName(),aDao,Data.class,TABLE,ConsistencyLevel.LOCAL_ONE,ConsistencyLevel.ANY);

+		init(trans);

+	}

+

+

+	private static final int KEYLIMIT = 1;

+	public static class Data {

+		public UUID id;

+		public int	yr_mon;

+		public String user;

+		public String action;

+		public String target;

+		public String subject;

+		public String  memo;

+//		Map<String, String>  detail = null;

+//		public Map<String, String>  detail() {

+//			if(detail == null) {

+//				detail = new HashMap<String, String>();

+//			}

+//			return detail;

+//		}

+		public ByteBuffer reconstruct;

+	}

+	

+	private static class HistLoader extends Loader<Data> {

+		public HistLoader(int keylimit) {

+			super(keylimit);

+		}

+

+		@Override

+		public Data load(Data data, Row row) {

+			data.id = row.getUUID(0);

+			data.yr_mon = row.getInt(1);

+			data.user = row.getString(2);

+			data.action = row.getString(3);

+			data.target = row.getString(4);

+			data.subject = row.getString(5);

+			data.memo = row.getString(6);

+//			data.detail = row.getMap(6, String.class, String.class);

+			data.reconstruct = row.getBytes(7);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int idx, Object[] obj) {

+			obj[idx]=data.id;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.yr_mon;

+			obj[++idx]=data.user;

+			obj[++idx]=data.action;

+			obj[++idx]=data.target;

+			obj[++idx]=data.subject;

+			obj[++idx]=data.memo;

+//			obj[++idx]=data.detail;

+			obj[++idx]=data.reconstruct;		

+		}

+	};

+	

+	private void init(AuthzTrans trans) {

+		// Loader must match fields order

+		defLoader = new HistLoader(KEYLIMIT);

+		helpers = setCRUD(trans, TABLE, Data.class, defLoader);

+

+		// Need a specialty Creator to handle the "now()"

+		// 9/9/2013 - jg - Just great... now() is evaluated once on Client side, invalidating usage (what point is a now() from a long time in the past?

+		// Unless this is fixed, we're putting in non-prepared statement

+		// Solved in Cassandra.  Make sure you are running 1.2.6 Cassandra or later. https://issues.apache.org/jira/browse/CASSANDRA-5616	

+		replace(CRUD.create, new PSInfo(trans, "INSERT INTO history (" +  helpers[FIELD_COMMAS] +

+					") VALUES(now(),?,?,?,?,?,?,?)", 

+					new HistLoader(0) {

+						@Override

+						protected void key(Data data, int idx, Object[] obj) {

+						}

+					},writeConsistency)

+				);

+//		disable(CRUD.Create);

+		

+		replace(CRUD.read, new PSInfo(trans, SELECT_SP +  helpers[FIELD_COMMAS] +

+				" FROM history WHERE id = ?", defLoader,readConsistency) 

+//				new HistLoader(2) {

+//					@Override

+//					protected void key(Data data, int idx, Object[] obj) {

+//						obj[idx]=data.yr_mon;

+//						obj[++idx]=data.id;

+//					}

+//				})

+			);

+		disable(CRUD.update);

+		disable(CRUD.delete);

+		

+		readByUser = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + 

+				" FROM history WHERE user = ?", defLoader,readConsistency);

+		readBySubject = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + 

+				" FROM history WHERE subject = ? and target = ? ALLOW FILTERING", defLoader,readConsistency);

+		readByYRMN = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + 

+				" FROM history WHERE yr_mon = ?", defLoader,readConsistency);

+		async(true); //TODO dropping messages with Async

+	}

+

+	public static Data newInitedData() {

+		Data data = new Data();

+		Date now = new Date();

+		data.yr_mon = Integer.parseInt(monthFormat.format(now));

+		// data.day_time = Integer.parseInt(dayTimeFormat.format(now));

+		return data;		

+	}

+

+	public Result<List<Data>> readByYYYYMM(AuthzTrans trans, int yyyymm) {

+		Result<ResultSet> rs = readByYRMN.exec(trans, "yr_mon", yyyymm);

+		if(rs.notOK()) {

+			return Result.err(rs);

+		}

+		return extract(defLoader,rs.value,null,dflt);

+	}

+

+	/**

+	 * Gets the history for a user in the specified year and month

+	 * year - the year in yyyy format

+	 * month -  the month in a year ...values 1 - 12

+	 **/

+	public Result<List<Data>> readByUser(AuthzTrans trans, String user, int ... yyyymm) {

+		if(yyyymm.length==0) {

+			return Result.err(Status.ERR_BadData, "No or invalid yyyymm specified");

+		}

+		Result<ResultSet> rs = readByUser.exec(trans, "user", user);

+		if(rs.notOK()) {

+			return Result.err(rs);

+		}

+		return extract(defLoader,rs.value,null,yyyymm.length>0?new YYYYMM(yyyymm):dflt);

+	}

+	

+	public Result<List<Data>> readBySubject(AuthzTrans trans, String subject, String target, int ... yyyymm) {

+		if(yyyymm.length==0) {

+			return Result.err(Status.ERR_BadData, "No or invalid yyyymm specified");

+		}

+		Result<ResultSet> rs = readBySubject.exec(trans, "subject", subject, target);

+		if(rs.notOK()) {

+			return Result.err(rs);

+		}

+		return extract(defLoader,rs.value,null,yyyymm.length>0?new YYYYMM(yyyymm):dflt);

+	}

+	

+	private class YYYYMM implements Accept<Data> {

+		private int[] yyyymm;

+		public YYYYMM(int yyyymm[]) {

+			this.yyyymm = yyyymm;

+		}

+		@Override

+		public boolean ok(Data data) {

+			int dym = data.yr_mon;

+			for(int ym:yyyymm) {

+				if(dym==ym) {

+					return true;

+				}

+			}

+			return false;

+		}

+		

+	};

+	

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Namespace.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Namespace.java
new file mode 100644
index 0000000..98c4616
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Namespace.java
@@ -0,0 +1,151 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Map.Entry;

+

+import org.onap.aaf.cssa.rserv.Pair;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+

+

+public class Namespace implements Bytification {

+	public static final int MAGIC=250935515;

+	public static final int VERSION=1;

+	public static final int BUFF_SIZE=48;

+

+	public String name;

+	public List<String> owner;

+	public List<String> admin;

+	public List<Pair<String,String>> attrib;

+	public String description;

+	public Integer type;

+	public String parent;

+	public Namespace() {}

+	

+	public Namespace(NsDAO.Data ndd) {

+		name = ndd.name;

+		description = ndd.description;

+		type = ndd.type;

+		parent = ndd.parent;

+		if(ndd.attrib!=null && !ndd.attrib.isEmpty()) {

+			attrib = new ArrayList<Pair<String,String>>();

+			for( Entry<String, String> entry : ndd.attrib.entrySet()) {

+				attrib.add(new Pair<String,String>(entry.getKey(),entry.getValue()));

+			}

+		}

+	}

+	

+	public Namespace(NsDAO.Data ndd,List<String> owner, List<String> admin) {

+		name = ndd.name;

+		this.owner = owner;

+		this.admin = admin;

+		description = ndd.description;

+		type = ndd.type;

+		parent = ndd.parent;

+		if(ndd.attrib!=null && !ndd.attrib.isEmpty()) {

+			attrib = new ArrayList<Pair<String,String>>();

+			for( Entry<String, String> entry : ndd.attrib.entrySet()) {

+				attrib.add(new Pair<String,String>(entry.getKey(),entry.getValue()));

+			}

+		}

+	}

+

+	public NsDAO.Data data() {

+		NsDAO.Data ndd = new NsDAO.Data();

+		ndd.name = name;

+		ndd.description = description;

+		ndd.parent = parent;

+		ndd.type = type;

+		return ndd;

+	}

+

+	@Override

+	public ByteBuffer bytify() throws IOException {

+		ByteArrayOutputStream baos = new ByteArrayOutputStream();

+		DataOutputStream os = new DataOutputStream(baos);

+

+		Loader.writeHeader(os,MAGIC,VERSION);

+		Loader.writeString(os, name);

+		os.writeInt(type);

+		Loader.writeStringSet(os,admin);

+		Loader.writeStringSet(os,owner);

+		Loader.writeString(os,description);

+		Loader.writeString(os,parent);

+

+		return ByteBuffer.wrap(baos.toByteArray());

+	}

+

+	@Override

+	public void reconstitute(ByteBuffer bb) throws IOException {

+		DataInputStream is = CassDAOImpl.toDIS(bb);

+		/*int version = */Loader.readHeader(is,MAGIC,VERSION);

+		// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+		

+		byte[] buff = new byte[BUFF_SIZE];

+		name = Loader.readString(is, buff);

+		type = is.readInt();

+		admin = Loader.readStringList(is,buff);

+		owner = Loader.readStringList(is,buff);

+		description = Loader.readString(is,buff);

+		parent = Loader.readString(is,buff);

+		

+	}

+

+	/* (non-Javadoc)

+	 * @see java.lang.Object#hashCode()

+	 */

+	@Override

+	public int hashCode() {

+		return name.hashCode();

+	}

+	

+

+	/* (non-Javadoc)

+	 * @see java.lang.Object#toString()

+	 */

+	@Override

+	public String toString() {

+		return name.toString();

+	}

+

+	/* (non-Javadoc)

+	 * @see java.lang.Object#equals(java.lang.Object)

+	 */

+	@Override

+	public boolean equals(Object arg0) {

+		if(arg0==null || !(arg0 instanceof Namespace)) {

+			return false;

+		}

+		return name.equals(((Namespace)arg0).name);

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsDAO.java
new file mode 100644
index 0000000..9e18195
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsDAO.java
@@ -0,0 +1,542 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Map.Entry;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+

+import java.util.Set;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.exceptions.DriverException;

+

+/**

+ * NsDAO

+ * 

+ * Data Access Object for Namespace Data

+ *

+ */

+public class NsDAO extends CassDAOImpl<AuthzTrans,NsDAO.Data> {

+	public static final String TABLE = "ns";

+	public static final String TABLE_ATTRIB = "ns_attrib";

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+    public static final int ROOT = 1;

+    public static final int COMPANY=2;

+    public static final int APP = 3;

+

+	private static final String BEGIN_BATCH = "BEGIN BATCH\n";

+	private static final String APPLY_BATCH = "APPLY BATCH;\n";

+	private static final String SQSCCR = "';\n";

+	private static final String SQCSQ = "','";

+    

+	private HistoryDAO historyDAO;

+	private CacheInfoDAO infoDAO;

+	private PSInfo psNS;

+

+	public NsDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+		super(trans, NsDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		init(trans);

+	}

+

+	public NsDAO(AuthzTrans trans, HistoryDAO hDAO, CacheInfoDAO iDAO) throws APIException, IOException {

+		super(trans, NsDAO.class.getSimpleName(),hDAO,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		historyDAO=hDAO;

+		infoDAO = iDAO;

+		init(trans);

+	}

+

+

+    //////////////////////////////////////////

+    // Data Definition, matches Cassandra DM

+    //////////////////////////////////////////

+    private static final int KEYLIMIT = 1;

+    /**

+     * Data class that matches the Cassandra Table "role"

+     * 

+     */

+	public static class Data extends CacheableData implements Bytification {

+		public String		      name;

+		public int			      type;

+		public String			  description;

+		public String			  parent;

+		public Map<String,String> attrib;

+

+//		////////////////////////////////////////

+//        // Getters

+		public Map<String,String> attrib(boolean mutable) {

+			if (attrib == null) {

+				attrib = new HashMap<String,String>();

+			} else if (mutable && !(attrib instanceof HashMap)) {

+				attrib = new HashMap<String,String>(attrib);

+			}

+			return attrib;

+		}

+

+		@Override

+		public int[] invalidate(Cached<?,?> cache) {

+			return new int[] {

+				seg(cache,name)

+			};

+		}

+

+		public NsSplit split(String name) {

+			return new NsSplit(this,name);

+		}

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			NSLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			NSLoader.deflt.unmarshal(this,toDIS(bb));

+		}

+		

+		@Override

+		public String toString() {

+			return name;

+		}

+		

+    }

+    

+    private void init(AuthzTrans trans) throws APIException, IOException {

+        // Set up sub-DAOs

+        if(historyDAO==null) {

+	    historyDAO = new HistoryDAO(trans, this);

+	}

+        if(infoDAO==null) {

+	    infoDAO = new CacheInfoDAO(trans,this);

+	}

+

+		String[] helpers = setCRUD(trans, TABLE, Data.class, NSLoader.deflt,4/*need to skip attrib */);

+		

+		psNS = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE parent = ?", new NSLoader(1),readConsistency);

+

+	}

+	

+    private static final class NSLoader extends Loader<Data> implements Streamer<Data> {

+		public static final int MAGIC=250935515;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48;

+

+    	public static final NSLoader deflt = new NSLoader(KEYLIMIT);

+    	

+		public NSLoader(int keylimit) {

+			super(keylimit);

+		}

+

+		@Override

+		public Data load(Data data, Row row) {

+			// Int more efficient

+			data.name = row.getString(0);

+			data.type = row.getInt(1);

+			data.description = row.getString(2);

+			data.parent = row.getString(3);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int idx, Object[] obj) {

+			obj[idx]=data.name;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+

+			obj[idx]=data.type;

+			obj[++idx]=data.description;

+			obj[++idx]=data.parent;

+		}

+		

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.name);

+			os.writeInt(data.type);

+			writeString(os,data.description);

+			writeString(os,data.parent);

+			if(data.attrib==null) {

+				os.writeInt(-1);

+			} else {

+				os.writeInt(data.attrib.size());

+				for(Entry<String, String> es : data.attrib(false).entrySet()) {

+					writeString(os,es.getKey());

+					writeString(os,es.getValue());

+				}

+			}

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			

+			byte[] buff = new byte[BUFF_SIZE];

+			data.name = readString(is, buff);

+			data.type = is.readInt();

+			data.description = readString(is,buff);

+			data.parent = readString(is,buff);

+			int count = is.readInt();

+			if(count>0) {

+				Map<String, String> da = data.attrib(true);

+				for(int i=0;i<count;++i) {

+					da.put(readString(is,buff), readString(is,buff));

+				}

+			}

+		}

+

+    }

+    

+	@Override

+	public Result<Data> create(AuthzTrans trans, Data data) {

+		String ns = data.name;

+		// Ensure Parent is set

+		int ldot = ns.lastIndexOf('.');

+		data.parent=ldot<0?".":ns.substring(0,ldot);

+

+		// insert Attributes

+		StringBuilder stmt = new StringBuilder();

+		stmt.append(BEGIN_BATCH);

+		attribInsertStmts(stmt, data);

+		stmt.append(APPLY_BATCH);

+		try {

+			getSession(trans).execute(stmt.toString());

+//// TEST CODE for Exception				

+//			boolean force = true; 

+//			if(force) {

+//				throw new com.datastax.driver.core.exceptions.NoHostAvailableException(new HashMap<InetSocketAddress,Throwable>());

+////				throw new com.datastax.driver.core.exceptions.AuthenticationException(new InetSocketAddress(9999),"Sample Message");

+//			}

+////END TEST CODE

+

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			trans.info().log(stmt);

+			return Result.err(Result.ERR_Backend, "Backend Access");

+		}

+		return super.create(trans, data);

+	}

+

+	@Override

+	public Result<Void> update(AuthzTrans trans, Data data) {

+		String ns = data.name;

+		// Ensure Parent is set

+		int ldot = ns.lastIndexOf('.');

+		data.parent=ldot<0?".":ns.substring(0,ldot);

+

+		StringBuilder stmt = new StringBuilder();

+		stmt.append(BEGIN_BATCH);

+		try {

+			Map<String, String> localAttr = data.attrib;

+			Result<Map<String, String>> rremoteAttr = readAttribByNS(trans,ns);

+			if(rremoteAttr.notOK()) {

+				return Result.err(rremoteAttr);

+			}

+			// update Attributes

+			String str;

+			for(Entry<String, String> es : localAttr.entrySet()) {

+				str = rremoteAttr.value.get(es.getKey());

+				if(str==null || !str.equals(es.getValue())) {

+					attribInsertStmt(stmt, ns, es.getKey(),es.getValue());

+				}

+			}

+			

+			// No point in deleting... insert overwrites...

+//			for(Entry<String, String> es : remoteAttr.entrySet()) {

+//				str = localAttr.get(es.getKey());

+//				if(str==null || !str.equals(es.getValue())) {

+//					attribDeleteStmt(stmt, ns, es.getKey());

+//				}

+//			}

+			if(stmt.length()>BEGIN_BATCH.length()) {

+				stmt.append(APPLY_BATCH);

+				getSession(trans).execute(stmt.toString());

+			}

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			trans.info().log(stmt);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		return super.update(trans,data);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.dao.CassDAOImpl#read(org.onap.aaf.inno.env.TransStore, java.lang.Object)

+	 */

+	@Override

+	public Result<List<Data>> read(AuthzTrans trans, Data data) {

+		Result<List<Data>> rld = super.read(trans, data);

+		

+		if(rld.isOKhasData()) {

+			for(Data d : rld.value) {

+				// Note: Map is null at this point, save time/mem by assignment

+				Result<Map<String, String>> rabn = readAttribByNS(trans,d.name);

+				if(rabn.isOK()) {

+					d.attrib = rabn.value;

+				} else {

+					return Result.err(rabn);

+				}

+			}

+		}

+		return rld;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.dao.CassDAOImpl#read(org.onap.aaf.inno.env.TransStore, java.lang.Object[])

+	 */

+	@Override

+	public Result<List<Data>> read(AuthzTrans trans, Object... key) {

+		Result<List<Data>> rld = super.read(trans, key);

+

+		if(rld.isOKhasData()) {

+			for(Data d : rld.value) {

+				// Note: Map is null at this point, save time/mem by assignment

+				Result<Map<String, String>> rabn = readAttribByNS(trans,d.name);

+				if(rabn.isOK()) {

+					d.attrib = rabn.value;

+				} else {

+					return Result.err(rabn);

+				}

+			}

+		}

+		return rld;

+	}

+

+	@Override

+	public Result<Void> delete(AuthzTrans trans, Data data, boolean reread) {

+		TimeTaken tt = trans.start("Delete NS Attributes " + data.name, Env.REMOTE);

+		try {

+			StringBuilder stmt = new StringBuilder();

+			attribDeleteAllStmt(stmt, data);

+			try {

+				getSession(trans).execute(stmt.toString());

+			} catch (DriverException | APIException | IOException e) {

+				reportPerhapsReset(trans,e);

+				trans.info().log(stmt);

+				return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+			}

+		} finally {

+			tt.done();

+		}

+		return super.delete(trans, data, reread);

+

+	}

+    

+	public Result<Map<String,String>> readAttribByNS(AuthzTrans trans, String ns) {

+		Map<String,String> map = new HashMap<String,String>();

+		TimeTaken tt = trans.start("readAttribByNS " + ns, Env.REMOTE);

+		try {

+			ResultSet rs = getSession(trans).execute("SELECT key,value FROM " 

+					+ TABLE_ATTRIB 

+					+ " WHERE ns='"

+					+ ns

+					+ "';");

+			

+			for(Iterator<Row> iter = rs.iterator();iter.hasNext(); ) {

+				Row r = iter.next();

+				map.put(r.getString(0), r.getString(1));

+			}

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		} finally {

+			tt.done();

+		}

+		return Result.ok(map);

+	}

+

+	public Result<Set<String>> readNsByAttrib(AuthzTrans trans, String key) {

+		Set<String> set = new HashSet<String>();

+		TimeTaken tt = trans.start("readNsBykey " + key, Env.REMOTE);

+		try {

+			ResultSet rs = getSession(trans).execute("SELECT ns FROM " 

+				+ TABLE_ATTRIB 

+				+ " WHERE key='"

+				+ key

+				+ "';");

+		

+			for(Iterator<Row> iter = rs.iterator();iter.hasNext(); ) {

+				Row r = iter.next();

+				set.add(r.getString(0));

+			}

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		} finally {

+			tt.done();

+		}

+		return Result.ok(set);

+	}

+

+	public Result<Void> attribAdd(AuthzTrans trans, String ns, String key, String value) {

+		try {

+			getSession(trans).execute(attribInsertStmt(new StringBuilder(),ns,key,value).toString());

+			return Result.ok();

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+	}

+	

+	private StringBuilder attribInsertStmt(StringBuilder sb, String ns, String key, String value) {

+		sb.append("INSERT INTO ");

+		sb.append(TABLE_ATTRIB);

+		sb.append(" (ns,key,value) VALUES ('");

+		sb.append(ns);

+		sb.append(SQCSQ);

+		sb.append(key);

+		sb.append(SQCSQ);

+		sb.append(value);

+		sb.append("');");

+		return sb;

+	}

+	

+	public Result<Void> attribRemove(AuthzTrans trans, String ns, String key) {

+		try {

+			getSession(trans).execute(attribDeleteStmt(new StringBuilder(),ns,key).toString());

+			return Result.ok();

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+	}

+	

+	private StringBuilder attribDeleteStmt(StringBuilder stmt, String ns, String key) {

+		stmt.append("DELETE FROM ");

+		stmt.append(TABLE_ATTRIB);

+		stmt.append(" WHERE ns='");

+		stmt.append(ns);

+		stmt.append("' AND key='");

+		stmt.append(key);

+		stmt.append("';");

+		return stmt;

+	}

+	

+	private void attribDeleteAllStmt(StringBuilder stmt, Data data) {

+		stmt.append("  DELETE FROM ");

+		stmt.append(TABLE_ATTRIB);

+		stmt.append(" WHERE ns='");

+		stmt.append(data.name);

+		stmt.append(SQSCCR);

+	}

+

+	private void attribInsertStmts(StringBuilder stmt, Data data) {

+		// INSERT new Attrib

+		for(Entry<String,String> es : data.attrib(false).entrySet() ) {

+			stmt.append("  ");

+			attribInsertStmt(stmt,data.name,es.getKey(),es.getValue());

+		}

+	}

+

+	/**

+	 * Add description to Namespace

+	 * @param trans

+	 * @param ns

+	 * @param description

+	 * @return

+	 */

+	public Result<Void> addDescription(AuthzTrans trans, String ns, String description) {

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET description = '" 

+				+ description + "' WHERE name = '" + ns + "';");

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		Data data = new Data();

+		data.name=ns;

+		wasModified(trans, CRUD.update, data, "Added description " + description + " to namespace " + ns, null );

+		return Result.ok();

+	}

+

+	public Result<List<Data>> getChildren(AuthzTrans trans, String parent) {

+		return psNS.read(trans, R_TEXT, new Object[]{parent});

+	}

+		

+

+    /**

+     * Log Modification statements to History

+     * 

+     * @param modified           which CRUD action was done

+     * @param data               entity data that needs a log entry

+     * @param overrideMessage    if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+        //TODO Must log history

+        HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject ? override[1] : data.name;

+        hd.memo = memo ? override[0] : (data.name + " was "  + modified.name() + 'd' );

+		if(modified==CRUD.delete) {

+			try {

+				hd.reconstruct = data.bytify();

+			} catch (IOException e) {

+				trans.error().log(e,"Could not serialize NsDAO.Data");

+			}

+		}

+

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+	    trans.error().log("Cannot log to History");

+	}

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).notOK()) {

+	    trans.error().log("Cannot touch CacheInfo");

+	}

+    }

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsSplit.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsSplit.java
new file mode 100644
index 0000000..21e5728
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsSplit.java
@@ -0,0 +1,62 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+public class NsSplit {

+	public final String ns;

+	public final String name;

+	public final NsDAO.Data nsd;

+	

+	public NsSplit(NsDAO.Data nsd, String child) {

+		this.nsd = nsd;

+		if(child.startsWith(nsd.name)) {

+			ns = nsd.name;

+			int dot = ns.length();

+			if(dot<child.length() && child.charAt(dot)=='.') {

+    			name = child.substring(dot+1);

+			} else {

+				name="";

+			}

+		} else {

+			name=null;

+			ns = null;

+		}

+	}

+	

+	public NsSplit(String ns, String name) {

+		this.ns = ns;

+		this.name = name;

+		this.nsd = new NsDAO.Data();

+		nsd.name = ns;

+		int dot = ns.lastIndexOf('.');

+		if(dot>=0) {

+			nsd.parent = ns.substring(0, dot);

+		} else {

+			nsd.parent = ".";

+		}

+	}

+

+	public boolean isOK() {

+		return ns!=null && name !=null;

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsType.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsType.java
new file mode 100644
index 0000000..c098acb
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/NsType.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+/**

+ * Defines the Type Codes in the NS Table.

+ *

+ */

+public enum NsType {

+		UNKNOWN (-1),

+		DOT (0),

+		ROOT (1), 

+		COMPANY (2), 

+		APP (3), 

+		STACKED_APP (10), 

+		STACK (11);

+		

+		public final int type;

+		private NsType(int t) {

+			type = t;

+		}

+		/**

+		 * This is not the Ordinal, but the Type that is stored in NS Tables

+		 * 

+		 * @param t

+		 * @return

+		 */

+		public static NsType fromType(int t) {

+			for(NsType nst : values()) {

+				if(t==nst.type) {

+					return nst;

+				}

+			}

+			return UNKNOWN;

+		}

+		

+		/**

+		 * Use this one rather than "valueOf" to avoid Exception

+		 * @param s

+		 * @return

+		 */

+		public static NsType fromString(String s) {

+			if(s!=null) {

+				for(NsType nst : values()) {

+					if(nst.name().equals(s)) {

+						return nst;

+					}

+				}

+			}

+			return UNKNOWN;

+		}

+

+		

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/PermDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/PermDAO.java
new file mode 100644
index 0000000..e0b368f
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/PermDAO.java
@@ -0,0 +1,502 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Split;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.exceptions.DriverException;

+

+public class PermDAO extends CassDAOImpl<AuthzTrans,PermDAO.Data> {

+

+	public static final String TABLE = "perm";

+

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+	private static final String STAR = "*";

+	

+	private final HistoryDAO historyDAO;

+	private final CacheInfoDAO infoDAO;

+	

+	private PSInfo psNS, psChildren, psByType;

+

+	public PermDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+		super(trans, PermDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		init(trans);

+		historyDAO = new HistoryDAO(trans, this);

+		infoDAO = new CacheInfoDAO(trans,this);

+	}

+

+	public PermDAO(AuthzTrans trans, HistoryDAO hDAO, CacheInfoDAO ciDAO) {

+		super(trans, PermDAO.class.getSimpleName(),hDAO,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		historyDAO = hDAO;

+		infoDAO=ciDAO;

+		init(trans);

+	}

+

+

+	private static final int KEYLIMIT = 4;

+	public static class Data extends CacheableData implements Bytification {

+		public String		ns;

+		public String		type;

+		public String		instance;

+		public String		action;

+		public Set<String>  roles; 

+		public String		description;

+

+		public Data() {}

+		

+		public Data(NsSplit nss, String instance, String action) {

+			ns = nss.ns;

+			type = nss.name;

+			this.instance = instance;

+			this.action = action;

+		}

+

+		public String fullType() {

+			return ns + '.' + type;

+		}

+		

+		public String fullPerm() {

+			return ns + '.' + type + '|' + instance + '|' + action;

+		}

+

+		public String encode() {

+			return ns + '|' + type + '|' + instance + '|' + action;

+		}

+		

+		/**

+		 * Decode Perm String, including breaking into appropriate Namespace

+		 * 

+		 * @param trans

+		 * @param q

+		 * @param p

+		 * @return

+		 */

+		public static Result<Data> decode(AuthzTrans trans, Question q, String p) {

+			String[] ss = Split.splitTrim('|', p,4);

+			if(ss[2]==null) {

+				return Result.err(Status.ERR_BadData,"Perm Encodings must be separated by '|'");

+			}

+			Data data = new Data();

+			if(ss[3]==null) { // older 3 part encoding must be evaluated for NS

+				Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);

+				if(nss.notOK()) {

+					return Result.err(nss);

+				}

+				data.ns=nss.value.ns;

+				data.type=nss.value.name;

+				data.instance=ss[1];

+				data.action=ss[2];

+			} else { // new 4 part encoding

+				data.ns=ss[0];

+				data.type=ss[1];

+				data.instance=ss[2];

+				data.action=ss[3];

+			}

+			return Result.ok(data);

+		}

+

+		/**

+		 * Decode Perm String, including breaking into appropriate Namespace

+		 * 

+		 * @param trans

+		 * @param q

+		 * @param p

+		 * @return

+		 */

+		public static Result<String[]> decodeToArray(AuthzTrans trans, Question q, String p) {

+			String[] ss = Split.splitTrim('|', p,4);

+			if(ss[2]==null) {

+				return Result.err(Status.ERR_BadData,"Perm Encodings must be separated by '|'");

+			}

+			

+			if(ss[3]==null) { // older 3 part encoding must be evaluated for NS

+				ss[3] = ss[2];

+				ss[2] = ss[1];

+				Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);

+				if(nss.notOK()) {

+					return Result.err(nss);

+				}

+				ss[1] = nss.value.name;

+				ss[0] = nss.value.ns;

+			}

+			return Result.ok(ss);

+		}

+

+		public static Data create(NsDAO.Data ns, String name) {

+			NsSplit nss = new NsSplit(ns,name);

+			Data rv = new Data();

+			rv.ns = nss.ns;

+			String[] s = nss.name.split("\\|");

+			switch(s.length) {

+				case 3:

+					rv.type=s[0];

+					rv.instance=s[1];

+					rv.action=s[2];

+					break;

+				case 2:

+					rv.type=s[0];

+					rv.instance=s[1];

+					rv.action=STAR;

+					break;

+				default:

+					rv.type=s[0];

+					rv.instance = STAR;

+					rv.action = STAR;

+			}

+			return rv;

+		}

+		

+		public static Data create(AuthzTrans trans, Question q, String name) {

+			String[] s = name.split("\\|");

+			Result<NsSplit> rdns = q.deriveNsSplit(trans, s[0]);

+			Data rv = new PermDAO.Data();

+			if(rdns.isOKhasData()) {

+				switch(s.length) {

+					case 3:

+						rv.type=s[1];

+						rv.instance=s[2];

+						rv.action=s[3];

+						break;

+					case 2:

+						rv.type=s[1];

+						rv.instance=s[2];

+						rv.action=STAR;

+						break;

+					default:

+						rv.type=s[1];

+						rv.instance = STAR;

+						rv.action = STAR;

+				}

+			}

+			return rv;

+		}

+		

+        ////////////////////////////////////////

+        // Getters

+        public Set<String> roles(boolean mutable) {

+            if (roles == null) {

+                roles = new HashSet<String>();

+            } else if (mutable && !(roles instanceof HashSet)) {

+                roles = new HashSet<String>(roles);

+            }

+            return roles;

+        }

+

+		@Override

+		public int[] invalidate(Cached<?,?> cache) {

+			return new int[] {

+				seg(cache,ns),

+				seg(cache,ns,type),

+				seg(cache,ns,type,STAR),

+				seg(cache,ns,type,instance,action)

+			};

+		}

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			PermLoader.deflt.marshal(this, new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			PermLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+

+		@Override

+		public String toString() {

+			return encode();

+		}

+	}

+	

+	private static class PermLoader extends Loader<Data> implements Streamer<Data> {

+		public static final int MAGIC=283939453;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=96;

+

+    	public static final PermLoader deflt = new PermLoader(KEYLIMIT);

+    	

+		public PermLoader(int keylimit) {

+			super(keylimit);

+		}

+		

+		@Override

+		public Data load(Data data, Row row) {

+			// Int more efficient Match "fields" string

+			data.ns = row.getString(0);

+			data.type = row.getString(1);

+			data.instance = row.getString(2);

+			data.action = row.getString(3);

+			data.roles = row.getSet(4,String.class);

+			data.description = row.getString(5);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.ns;

+			obj[++idx]=data.type;

+			obj[++idx]=data.instance;

+			obj[++idx]=data.action;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.roles;

+			obj[++idx]=data.description;

+		}

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.ns);

+			writeString(os, data.type);

+			writeString(os, data.instance);

+			writeString(os, data.action);

+			writeStringSet(os, data.roles);

+			writeString(os, data.description);

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.ns = readString(is, buff);

+			data.type = readString(is,buff);

+			data.instance = readString(is,buff);

+			data.action = readString(is,buff);

+			data.roles = readStringSet(is,buff);

+			data.description = readString(is,buff);

+		}

+	}

+	

+	private void init(AuthzTrans trans) {

+		// the 3 is the number of key fields

+		String[] helpers = setCRUD(trans, TABLE, Data.class, PermLoader.deflt);

+		

+		// Other SELECT style statements... match with a local Method

+		psByType = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE + 

+				" WHERE ns = ? AND type = ?", new PermLoader(2) {

+			@Override

+			protected void key(Data data, int idx, Object[] obj) {

+				obj[idx]=data.type;

+			}

+		},readConsistency);

+		

+		psNS = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE ns = ?", new PermLoader(1),readConsistency);

+				

+		psChildren = new PSInfo(trans, SELECT_SP +  helpers[FIELD_COMMAS] +  " FROM " + TABLE + 

+				" WHERE ns=? AND type > ? AND type < ?", 

+				new PermLoader(3) {

+			@Override

+			protected void key(Data data, int _idx, Object[] obj) {

+			    	int idx = _idx;

+				obj[idx] = data.ns;

+				obj[++idx]=data.type + DOT;

+				obj[++idx]=data.type + DOT_PLUS_ONE;

+			}

+		},readConsistency);

+

+	}

+

+

+	/**

+	 * Add a single Permission to the Role's Permission Collection

+	 * 

+	 * @param trans

+	 * @param roleFullName

+	 * @param perm

+	 * @param type

+	 * @param action

+	 * @return

+	 */

+	public Result<Void> addRole(AuthzTrans trans, PermDAO.Data perm, String roleFullName) {

+		// Note: Prepared Statements for Collection updates aren't supported

+		//ResultSet rv =

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET roles = roles + {'"	+ roleFullName + "'} " +

+				"WHERE " +

+					"ns = '" + perm.ns + "' AND " +

+					"type = '" + perm.type + "' AND " +

+					"instance = '" + perm.instance + "' AND " +

+					"action = '" + perm.action + "';"

+					);

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		wasModified(trans, CRUD.update, perm, "Added role " + roleFullName + " to perm " +

+				perm.ns + '.' + perm.type + '|' + perm.instance + '|' + perm.action);

+		return Result.ok();

+	}

+

+	/**

+	 * Remove a single Permission from the Role's Permission Collection

+	 * @param trans

+	 * @param roleFullName

+	 * @param perm

+	 * @param type

+	 * @param action

+	 * @return

+	 */

+	public Result<Void> delRole(AuthzTrans trans, PermDAO.Data perm, String roleFullName) {

+		// Note: Prepared Statements for Collection updates aren't supported

+		//ResultSet rv =

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET roles = roles - {'" + roleFullName + "'} " +

+				"WHERE " +

+					"ns = '" + perm.ns + "' AND " +

+					"type = '" + perm.type + "' AND " +

+					"instance = '" + perm.instance + "' AND " +

+					"action = '" + perm.action + "';"

+					);

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		//TODO how can we tell when it doesn't?

+		wasModified(trans, CRUD.update, perm, "Removed role " + roleFullName + " from perm " +

+				perm.ns + '.' + perm.type + '|' + perm.instance + '|' + perm.action);

+		return Result.ok();

+	}

+

+

+	

+	/**

+	 * Additional method: 

+	 * 		Select all Permissions by Name

+	 * 

+	 * @param name

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<List<Data>> readByType(AuthzTrans trans, String ns, String type) {

+		return psByType.read(trans, R_TEXT, new Object[]{ns, type});

+	}

+	

+	public Result<List<Data>> readChildren(AuthzTrans trans, String ns, String type) {

+		return psChildren.read(trans, R_TEXT, new Object[]{ns, type+DOT, type + DOT_PLUS_ONE});

+	}

+

+	public Result<List<Data>> readNS(AuthzTrans trans, String ns) {

+		return psNS.read(trans, R_TEXT, new Object[]{ns});

+	}

+

+	/**

+	 * Add description to this permission

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @param description

+	 * @return

+	 */

+	public Result<Void> addDescription(AuthzTrans trans, String ns, String type,

+			String instance, String action, String description) {

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET description = '" 

+				+ description + "' WHERE ns = '" + ns + "' AND type = '" + type + "'"

+				+ "AND instance = '" + instance + "' AND action = '" + action + "';");

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		Data data = new Data();

+		data.ns=ns;

+		data.type=type;

+		data.instance=instance;

+		data.action=action;

+		wasModified(trans, CRUD.update, data, "Added description " + description + " to permission " 

+				+ data.encode(), null );

+		return Result.ok();

+	}

+	

+	/**

+	 * Log Modification statements to History

+	 */

+	@Override

+	protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+		// Need to update history

+		HistoryDAO.Data hd = HistoryDAO.newInitedData();

+		hd.user = trans.user();

+		hd.action = modified.name();

+		hd.target = TABLE;

+		hd.subject = subject ? override[1] : data.fullType();

+		if (memo) {

+            hd.memo = String.format("%s", override[0]);

+        } else {

+            hd.memo = String.format("%sd %s|%s|%s", modified.name(),data.fullType(),data.instance,data.action);

+        }

+		

+		if(modified==CRUD.delete) {

+			try {

+				hd.reconstruct = data.bytify();

+			} catch (IOException e) {

+				trans.error().log(e,"Could not serialize PermDAO.Data");

+			}

+		}

+		

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).notOK()) {

+        	trans.error().log("Cannot touch CacheInfo");

+        }

+	}

+}

+

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/RoleDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/RoleDAO.java
new file mode 100644
index 0000000..5b0190e
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/RoleDAO.java
@@ -0,0 +1,412 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Split;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.exceptions.DriverException;

+

+public class RoleDAO extends CassDAOImpl<AuthzTrans,RoleDAO.Data> {

+

+	public static final String TABLE = "role";

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+    

+	private final HistoryDAO historyDAO;

+	private final CacheInfoDAO infoDAO;

+

+	private PSInfo psChildren, psNS, psName;

+

+	public RoleDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+		super(trans, RoleDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+        // Set up sub-DAOs

+        historyDAO = new HistoryDAO(trans, this);

+		infoDAO = new CacheInfoDAO(trans,this);

+		init(trans);

+	}

+

+	public RoleDAO(AuthzTrans trans, HistoryDAO hDAO, CacheInfoDAO ciDAO) {

+		super(trans, RoleDAO.class.getSimpleName(),hDAO,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		historyDAO = hDAO;

+		infoDAO = ciDAO;

+		init(trans);

+	}

+

+

+    //////////////////////////////////////////

+    // Data Definition, matches Cassandra DM

+    //////////////////////////////////////////

+    private static final int KEYLIMIT = 2;

+    /**

+     * Data class that matches the Cassandra Table "role"

+     */

+	public static class Data extends CacheableData implements Bytification {

+    	public String		ns;

+		public String		name;

+		public Set<String>  perms;

+		public String		description;

+

+        ////////////////////////////////////////

+        // Getters

+		public Set<String> perms(boolean mutable) {

+			if (perms == null) {

+				perms = new HashSet<String>();

+			} else if (mutable && !(perms instanceof HashSet)) {

+				perms = new HashSet<String>(perms);

+			}

+			return perms;

+		}

+		

+		public static Data create(NsDAO.Data ns, String name) {

+			NsSplit nss = new NsSplit(ns,name);		

+			RoleDAO.Data rv = new Data();

+			rv.ns = nss.ns;

+			rv.name=nss.name;

+			return rv;

+		}

+		

+		public String fullName() {

+			return ns + '.' + name;

+		}

+		

+		public String encode() {

+			return ns + '|' + name;

+		}

+		

+		/**

+		 * Decode Perm String, including breaking into appropriate Namespace

+		 * 

+		 * @param trans

+		 * @param q

+		 * @param r

+		 * @return

+		 */

+		public static Result<Data> decode(AuthzTrans trans, Question q, String r) {

+			String[] ss = Split.splitTrim('|', r,2);

+			Data data = new Data();

+			if(ss[1]==null) { // older 1 part encoding must be evaluated for NS

+				Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);

+				if(nss.notOK()) {

+					return Result.err(nss);

+				}

+				data.ns=nss.value.ns;

+				data.name=nss.value.name;

+			} else { // new 4 part encoding

+				data.ns=ss[0];

+				data.name=ss[1];

+			}

+			return Result.ok(data);

+		}

+

+		/**

+		 * Decode from UserRole Data

+		 * @param urdd

+		 * @return

+		 */

+		public static RoleDAO.Data decode(UserRoleDAO.Data urdd) {

+			RoleDAO.Data rd = new RoleDAO.Data();

+			rd.ns = urdd.ns;

+			rd.name = urdd.rname;

+			return rd;

+		}

+

+

+		/**

+		 * Decode Perm String, including breaking into appropriate Namespace

+		 * 

+		 * @param trans

+		 * @param q

+		 * @param p

+		 * @return

+		 */

+		public static Result<String[]> decodeToArray(AuthzTrans trans, Question q, String p) {

+			String[] ss = Split.splitTrim('|', p,2);

+			if(ss[1]==null) { // older 1 part encoding must be evaluated for NS

+				Result<NsSplit> nss = q.deriveNsSplit(trans, ss[0]);

+				if(nss.notOK()) {

+					return Result.err(nss);

+				}

+				ss[0] = nss.value.ns;

+				ss[1] = nss.value.name;

+			}

+			return Result.ok(ss);

+		}

+		

+		@Override

+		public int[] invalidate(Cached<?,?> cache) {

+			return new int[] {

+				seg(cache,ns,name),

+				seg(cache,ns),

+				seg(cache,name),

+			};

+		}

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			RoleLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			RoleLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+

+		@Override

+		public String toString() {

+			return ns + '.' + name;

+		}

+    }

+

+    private static class RoleLoader extends Loader<Data> implements Streamer<Data> {

+		public static final int MAGIC=923577343;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=96;

+

+    	public static final RoleLoader deflt = new RoleLoader(KEYLIMIT);

+    	

+		public RoleLoader(int keylimit) {

+			super(keylimit);

+		}

+		

+		@Override

+		public Data load(Data data, Row row) {

+			// Int more efficient

+			data.ns = row.getString(0);

+			data.name = row.getString(1);

+			data.perms = row.getSet(2,String.class);

+			data.description = row.getString(3);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.ns;

+			obj[++idx]=data.name;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.perms;

+			obj[++idx]=data.description;

+		}

+

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+			writeString(os, data.ns);

+			writeString(os, data.name);

+			writeStringSet(os,data.perms);

+			writeString(os, data.description);

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			byte[] buff = new byte[BUFF_SIZE];

+			data.ns = readString(is, buff);

+			data.name = readString(is,buff);

+			data.perms = readStringSet(is,buff);

+			data.description = readString(is,buff);

+		}

+    };

+

+	private void init(AuthzTrans trans) {

+		String[] helpers = setCRUD(trans, TABLE, Data.class, RoleLoader.deflt);

+		

+		psNS = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE ns = ?", new RoleLoader(1),readConsistency);

+

+		psName = new PSInfo(trans, SELECT_SP + helpers[FIELD_COMMAS] + " FROM " + TABLE +

+				" WHERE name = ?", new RoleLoader(1),readConsistency);

+

+		psChildren = new PSInfo(trans, SELECT_SP +  helpers[FIELD_COMMAS] +  " FROM " + TABLE + 

+				" WHERE ns=? AND name > ? AND name < ?", 

+				new RoleLoader(3) {

+			@Override

+			protected void key(Data data, int _idx, Object[] obj) {

+			    	int idx = _idx;

+				obj[idx] = data.ns;

+				obj[++idx]=data.name + DOT;

+				obj[++idx]=data.name + DOT_PLUS_ONE;

+			}

+		},readConsistency);

+		

+	}

+

+	public Result<List<Data>> readNS(AuthzTrans trans, String ns) {

+		return psNS.read(trans, R_TEXT + " NS " + ns, new Object[]{ns});

+	}

+

+	public Result<List<Data>> readName(AuthzTrans trans, String name) {

+		return psName.read(trans, R_TEXT + name, new Object[]{name});

+	}

+

+	public Result<List<Data>> readChildren(AuthzTrans trans, String ns, String role) {

+		if(role.length()==0 || "*".equals(role)) {

+			return psChildren.read(trans, R_TEXT, new Object[]{ns, FIRST_CHAR, LAST_CHAR}); 

+		} else {

+			return psChildren.read(trans, R_TEXT, new Object[]{ns, role+DOT, role+DOT_PLUS_ONE});

+		}

+	}

+

+	/**

+	 * Add a single Permission to the Role's Permission Collection

+	 * 

+	 * @param trans

+	 * @param role

+	 * @param perm

+	 * @param type

+	 * @param action

+	 * @return

+	 */

+	public Result<Void> addPerm(AuthzTrans trans, RoleDAO.Data role, PermDAO.Data perm) {

+		// Note: Prepared Statements for Collection updates aren't supported

+		String pencode = perm.encode();

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET perms = perms + {'" + 

+				pencode + "'} WHERE " +

+				"ns = '" + role.ns + "' AND name = '" + role.name + "';");

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		wasModified(trans, CRUD.update, role, "Added permission " + pencode + " to role " + role.fullName());

+		return Result.ok();

+	}

+

+	/**

+	 * Remove a single Permission from the Role's Permission Collection

+	 * @param trans

+	 * @param role

+	 * @param perm

+	 * @param type

+	 * @param action

+	 * @return

+	 */

+	public Result<Void> delPerm(AuthzTrans trans, RoleDAO.Data role, PermDAO.Data perm) {

+		// Note: Prepared Statements for Collection updates aren't supported

+

+		String pencode = perm.encode();

+		

+		//ResultSet rv =

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET perms = perms - {'" + 

+				pencode	+ "'} WHERE " +

+				"ns = '" + role.ns + "' AND name = '" + role.name + "';");

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		//TODO how can we tell when it doesn't?

+		wasModified(trans, CRUD.update, role, "Removed permission " + pencode + " from role " + role.fullName() );

+		return Result.ok();

+	}

+	

+	/**

+	 * Add description to role

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param name

+	 * @param description

+	 * @return

+	 */

+	public Result<Void> addDescription(AuthzTrans trans, String ns, String name, String description) {

+		try {

+			getSession(trans).execute(UPDATE_SP + TABLE + " SET description = '" 

+				+ description + "' WHERE ns = '" + ns + "' AND name = '" + name + "';");

+		} catch (DriverException | APIException | IOException e) {

+			reportPerhapsReset(trans,e);

+			return Result.err(Result.ERR_Backend, CassAccess.ERR_ACCESS_MSG);

+		}

+

+		Data data = new Data();

+		data.ns=ns;

+		data.name=name;

+		wasModified(trans, CRUD.update, data, "Added description " + description + " to role " + data.fullName(), null );

+		return Result.ok();

+	}

+	

+	

+    /**

+     * Log Modification statements to History

+     * @param modified           which CRUD action was done

+     * @param data               entity data that needs a log entry

+     * @param overrideMessage    if this is specified, we use it rather than crafting a history message based on data

+     */

+    @Override

+    protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+    	HistoryDAO.Data hd = HistoryDAO.newInitedData();

+        hd.user = trans.user();

+        hd.action = modified.name();

+        hd.target = TABLE;

+        hd.subject = subject ? override[1] : data.fullName();

+        hd.memo = memo ? override[0] : (data.fullName() + " was "  + modified.name() + 'd' );

+		if(modified==CRUD.delete) {

+			try {

+				hd.reconstruct = data.bytify();

+			} catch (IOException e) {

+				trans.error().log(e,"Could not serialize RoleDAO.Data");

+			}

+		}

+

+        if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+        }

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).notOK()) {

+        	trans.error().log("Cannot touch CacheInfo for Role");

+        }

+    }

+

+    

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Status.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Status.java
new file mode 100644
index 0000000..246df6a
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/Status.java
@@ -0,0 +1,88 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import org.onap.aaf.authz.layer.Result;

+

+

+

+

+/**

+ * Add additional Behavior for Specific Applications for Results

+ * 

+ * In this case, we add additional BitField information accessible by

+ * method (

+ *

+ * @param <RV>

+ */

+public class Status<RV> extends Result<RV> {

+	

+	// 10/1/2013:  Initially, I used enum, but it's not extensible.

+    public final static int ERR_NsNotFound = Result.ERR_General+1,

+    						ERR_RoleNotFound = Result.ERR_General+2,

+    						ERR_PermissionNotFound = Result.ERR_General+3, 

+    						ERR_UserNotFound = Result.ERR_General+4,

+    						ERR_UserRoleNotFound = Result.ERR_General+5,

+    						ERR_DelegateNotFound = Result.ERR_General+6,

+    						ERR_InvalidDelegate = Result.ERR_General+7,

+    						ERR_DependencyExists = Result.ERR_General+8,

+    						ERR_NoApprovals = Result.ERR_General+9,

+    						ACC_Now = Result.ERR_General+10,

+    						ACC_Future = Result.ERR_General+11,

+    						ERR_ChoiceNeeded = Result.ERR_General+12,

+    						ERR_FutureNotRequested = Result.ERR_General+13;

+  

+	/**

+     * Constructor for Result set. 

+     * @param data

+     * @param status

+     */

+    private Status(RV value, int status, String details, String[] variables ) {

+    	super(value,status,details,variables);

+    }

+

+	public static String name(int status) {

+		switch(status) {

+			case OK: return "OK";

+			case ERR_NsNotFound: return "ERR_NsNotFound";

+			case ERR_RoleNotFound: return "ERR_RoleNotFound";

+			case ERR_PermissionNotFound: return "ERR_PermissionNotFound"; 

+			case ERR_UserNotFound: return "ERR_UserNotFound";

+			case ERR_UserRoleNotFound: return "ERR_UserRoleNotFound";

+			case ERR_DelegateNotFound: return "ERR_DelegateNotFound";

+			case ERR_InvalidDelegate: return "ERR_InvalidDelegate";

+			case ERR_ConflictAlreadyExists: return "ERR_ConflictAlreadyExists";

+			case ERR_DependencyExists: return "ERR_DependencyExists";

+			case ERR_ActionNotCompleted: return "ERR_ActionNotCompleted";

+			case ERR_Denied: return "ERR_Denied";

+			case ERR_Policy: return "ERR_Policy";

+			case ERR_BadData: return "ERR_BadData";

+			case ERR_NotImplemented: return "ERR_NotImplemented";

+			case ERR_NotFound: return "ERR_NotFound";

+			case ERR_ChoiceNeeded: return "ERR_ChoiceNeeded";

+		}

+		//case ERR_General:   or unknown... 

+		return "ERR_General";

+	}

+    

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/UserRoleDAO.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/UserRoleDAO.java
new file mode 100644
index 0000000..2968160
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/cass/UserRoleDAO.java
@@ -0,0 +1,320 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.cass;

+

+import java.io.ByteArrayOutputStream;

+import java.io.DataInputStream;

+import java.io.DataOutputStream;

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.Loader;

+import org.onap.aaf.dao.Streamer;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.util.Chrono;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Row;

+

+public class UserRoleDAO extends CassDAOImpl<AuthzTrans,UserRoleDAO.Data> {

+	public static final String TABLE = "user_role";

+	

+    public static final int CACHE_SEG = 0x40; // yields segment 0x0-0x3F

+

+	private static final String TRANS_UR_SLOT = "_TRANS_UR_SLOT_";

+	public Slot transURSlot;

+	

+	private final HistoryDAO historyDAO;

+	private final CacheInfoDAO infoDAO;

+	

+	private PSInfo psByUser, psByRole, psUserInRole;

+

+

+

+	public UserRoleDAO(AuthzTrans trans, Cluster cluster, String keyspace) throws APIException, IOException {

+		super(trans, UserRoleDAO.class.getSimpleName(),cluster,keyspace,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		transURSlot = trans.slot(TRANS_UR_SLOT);

+		init(trans);

+

+		// Set up sub-DAOs

+		historyDAO = new HistoryDAO(trans, this);

+		infoDAO = new CacheInfoDAO(trans,this);

+	}

+

+	public UserRoleDAO(AuthzTrans trans, HistoryDAO hDAO, CacheInfoDAO ciDAO) {

+		super(trans, UserRoleDAO.class.getSimpleName(),hDAO,Data.class,TABLE, readConsistency(trans,TABLE), writeConsistency(trans,TABLE));

+		transURSlot = trans.slot(TRANS_UR_SLOT);

+		historyDAO = hDAO;

+		infoDAO = ciDAO;

+		init(trans);

+	}

+

+	private static final int KEYLIMIT = 2;

+	public static class Data extends CacheableData implements Bytification {

+		public String  user;

+		public String  role;

+		public String  ns; 

+		public String  rname; 

+		public Date   expires;

+		

+		@Override

+		public int[] invalidate(Cached<?,?> cache) {

+			// Note: I'm not worried about Name collisions, because the formats are different:

+			// myName ... etc versus

+			// com. ...

+			// The "dot" makes the difference.

+			return new int[] {

+				seg(cache,user,role),

+				seg(cache,user),

+				seg(cache,role)

+			};

+		}

+

+		@Override

+		public ByteBuffer bytify() throws IOException {

+			ByteArrayOutputStream baos = new ByteArrayOutputStream();

+			URLoader.deflt.marshal(this,new DataOutputStream(baos));

+			return ByteBuffer.wrap(baos.toByteArray());

+		}

+		

+		@Override

+		public void reconstitute(ByteBuffer bb) throws IOException {

+			URLoader.deflt.unmarshal(this, toDIS(bb));

+		}

+

+		public void role(String ns, String rname) {

+			this.ns = ns;

+			this.rname = rname;

+			this.role = ns + '.' + rname;

+		}

+		

+		public void role(RoleDAO.Data rdd) {

+			ns = rdd.ns;

+			rname = rdd.name;

+			role = rdd.fullName();

+		}

+

+		

+		public boolean role(AuthzTrans trans, Question ques, String role) {

+			this.role = role;

+			Result<NsSplit> rnss = ques.deriveNsSplit(trans, role);

+			if(rnss.isOKhasData()) {

+				ns = rnss.value.ns;

+				rname = rnss.value.name;

+				return true;

+			} else {

+				return false;

+			}

+		}

+

+		@Override

+		public String toString() {

+			return user + '|' + ns + '|' +  rname + '|' + Chrono.dateStamp(expires);

+		}

+

+

+	}

+	

+	private static class URLoader extends Loader<Data> implements Streamer<Data> {

+		public static final int MAGIC=738469903;

+    	public static final int VERSION=1;

+    	public static final int BUFF_SIZE=48;

+    	

+    	public static final URLoader deflt = new URLoader(KEYLIMIT);

+

+		public URLoader(int keylimit) {

+			super(keylimit);

+		}

+

+		@Override

+		public Data load(Data data, Row row) {

+			data.user = row.getString(0);

+			data.role = row.getString(1);

+			data.ns = row.getString(2);

+			data.rname = row.getString(3);

+			data.expires = row.getDate(4);

+			return data;

+		}

+

+		@Override

+		protected void key(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.user;

+			obj[++idx]=data.role;

+		}

+

+		@Override

+		protected void body(Data data, int _idx, Object[] obj) {

+		    	int idx = _idx;

+			obj[idx]=data.ns;

+			obj[++idx]=data.rname;

+			obj[++idx]=data.expires;

+		}

+		

+		@Override

+		public void marshal(Data data, DataOutputStream os) throws IOException {

+			writeHeader(os,MAGIC,VERSION);

+

+			writeString(os, data.user);

+			writeString(os, data.role);

+			writeString(os, data.ns);

+			writeString(os, data.rname);

+			os.writeLong(data.expires==null?-1:data.expires.getTime());

+		}

+

+		@Override

+		public void unmarshal(Data data, DataInputStream is) throws IOException {

+			/*int version = */readHeader(is,MAGIC,VERSION);

+			// If Version Changes between Production runs, you'll need to do a switch Statement, and adequately read in fields

+			

+			byte[] buff = new byte[BUFF_SIZE];

+			data.user = readString(is,buff);

+			data.role = readString(is,buff);

+			data.ns = readString(is,buff);

+			data.rname = readString(is,buff);

+			long l = is.readLong();

+			data.expires = l<0?null:new Date(l);

+		}

+

+	};

+	

+	private void init(AuthzTrans trans) {

+		String[] helper = setCRUD(trans, TABLE, Data.class, URLoader.deflt);

+		

+		psByUser = new PSInfo(trans, SELECT_SP + helper[FIELD_COMMAS] + " FROM user_role WHERE user = ?", 

+			new URLoader(1) {

+				@Override

+				protected void key(Data data, int idx, Object[] obj) {

+					obj[idx]=data.user;

+				}

+			},readConsistency);

+		

+		// Note: We understand this call may have poor performance, so only should be used in Management (Delete) func

+		psByRole = new PSInfo(trans, SELECT_SP + helper[FIELD_COMMAS] + " FROM user_role WHERE role = ? ALLOW FILTERING", 

+				new URLoader(1) {

+					@Override

+					protected void key(Data data, int idx, Object[] obj) {

+						obj[idx]=data.role;

+					}

+				},readConsistency);

+		

+		psUserInRole = new PSInfo(trans,SELECT_SP + helper[FIELD_COMMAS] + " FROM user_role WHERE user = ? AND role = ?",

+				URLoader.deflt,readConsistency);

+	}

+

+	public Result<List<Data>> readByUser(AuthzTrans trans, String user) {

+		return psByUser.read(trans, R_TEXT + " by User " + user, new Object[]{user});

+	}

+

+	/**

+	 * Note: Use Sparingly. Cassandra's forced key structure means this will perform fairly poorly

+	 * @param trans

+	 * @param role

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<List<Data>> readByRole(AuthzTrans trans, String role) {

+		return psByRole.read(trans, R_TEXT + " by Role " + role, new Object[]{role});

+	}

+	

+	/**

+	 * Direct Lookup of User Role

+	 * Don't forget to check for Expiration

+	 */

+	public Result<List<Data>> readByUserRole(AuthzTrans trans, String user, String role) {

+		return psUserInRole.read(trans, R_TEXT + " by User " + user + " and Role " + role, new Object[]{user,role});

+	}

+

+

+	/**

+     * Log Modification statements to History

+     * @param modified           which CRUD action was done

+     * @param data               entity data that needs a log entry

+     * @param overrideMessage    if this is specified, we use it rather than crafting a history message based on data

+     */

+	@Override

+	protected void wasModified(AuthzTrans trans, CRUD modified, Data data, String ... override) {

+    	boolean memo = override.length>0 && override[0]!=null;

+    	boolean subject = override.length>1 && override[1]!=null;

+

+		HistoryDAO.Data hd = HistoryDAO.newInitedData();

+		HistoryDAO.Data hdRole = HistoryDAO.newInitedData();

+		

+        hd.user = hdRole.user = trans.user();

+		hd.action = modified.name();

+		// Modifying User/Role is an Update to Role, not a Create.  JG, 07-14-2015

+		hdRole.action = CRUD.update.name();

+		hd.target = TABLE;

+		hdRole.target = RoleDAO.TABLE;

+		hd.subject = subject?override[1] : (data.user + '|'+data.role);

+		hdRole.subject = data.role;

+		switch(modified) {

+			case create: 

+				hd.memo = hdRole.memo = memo

+					? String.format("%s by %s", override[0], hd.user)

+					: String.format("%s added to %s",data.user,data.role);	

+				break;

+			case update: 

+				hd.memo = hdRole.memo = memo

+					? String.format("%s by %s", override[0], hd.user)

+					: String.format("%s - %s was updated",data.user,data.role);

+				break;

+			case delete: 

+				hd.memo = hdRole.memo = memo

+					? String.format("%s by %s", override[0], hd.user)

+					: String.format("%s removed from %s",data.user,data.role);

+				try {

+					hd.reconstruct = hdRole.reconstruct = data.bytify();

+				} catch (IOException e) {

+					trans.warn().log(e,"Deleted UserRole could not be serialized");

+				}

+				break;

+			default:

+				hd.memo = hdRole.memo = memo

+				? String.format("%s by %s", override[0], hd.user)

+				: "n/a";

+		}

+

+		if(historyDAO.create(trans, hd).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+		}

+		

+		if(historyDAO.create(trans, hdRole).status!=Status.OK) {

+        	trans.error().log("Cannot log to History");

+		}

+		// uses User as Segment

+        if(infoDAO.touch(trans, TABLE,data.invalidate(cache)).notOK()) {

+        	trans.error().log("Cannot touch CacheInfo");

+        }

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/CassExecutor.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/CassExecutor.java
new file mode 100644
index 0000000..f05a917
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/CassExecutor.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.hl;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Executor;

+import org.onap.aaf.dao.aaf.cass.NsSplit;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+

+public class CassExecutor implements Executor {

+

+	private Question q;

+	private Function f;

+	private AuthzTrans trans;

+

+	public CassExecutor(AuthzTrans trans, Function f) {

+		this.trans = trans;

+		this.f = f;

+		this.q = this.f.q;

+	}

+

+	@Override

+	public boolean hasPermission(String user, String ns, String type, String instance, String action) {

+		return isGranted(user, ns, type, instance, action);

+	}

+

+	@Override

+	public boolean inRole(String name) {

+		Result<NsSplit> nss = q.deriveNsSplit(trans, name);

+		if(nss.notOK())return false;

+		return q.roleDAO.read(trans, nss.value.ns,nss.value.name).isOKhasData();

+	}

+

+	public boolean isGranted(String user, String ns, String type, String instance, String action) {

+		return q.isGranted(trans, user, ns, type, instance,action);

+	}

+

+	@Override

+	public String namespace() throws Exception {

+		Result<Data> res = q.validNSOfDomain(trans,trans.user());

+		if(res.isOK()) {

+			String user[] = trans.user().split("\\.");

+			return user[user.length-1] + '.' + user[user.length-2];

+		}

+		throw new Exception(res.status + ' ' + res.details);

+	}

+

+	@Override

+	public String id() {

+		return trans.user();

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Function.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Function.java
new file mode 100644
index 0000000..0404fee
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Function.java
@@ -0,0 +1,1574 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.hl;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+import java.util.UUID;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Executor;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.Organization.Expiration;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.authz.org.Organization.Policy;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.FutureDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.NsSplit;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+import org.onap.aaf.dao.aaf.hl.Question.Access;

+

+public class Function {

+

+	public static final String FOP_CRED = "cred";

+	public static final String FOP_DELEGATE = "delegate";

+	public static final String FOP_NS = "ns";

+	public static final String FOP_PERM = "perm";

+	public static final String FOP_ROLE = "role";

+	public static final String FOP_USER_ROLE = "user_role";

+	// First Action should ALWAYS be "write", see "CreateRole"

+	public final Question q;

+

+	public Function(AuthzTrans trans, Question question) {

+		q = question;

+	}

+

+	private class ErrBuilder {

+		private StringBuilder sb;

+		private List<String> ao;

+

+		public void log(Result<?> result) {

+			if (result.notOK()) {

+				if (sb == null) {

+					sb = new StringBuilder();

+					ao = new ArrayList<String>();

+				}

+				sb.append(result.details);

+				sb.append('\n');

+				for (String s : result.variables) {

+					ao.add(s);

+				}

+			}

+		}

+

+		public String[] vars() {

+			String[] rv = new String[ao.size()];

+			ao.toArray(rv);

+			return rv;

+		}

+

+		public boolean hasErr() {

+			return sb != null;

+		}

+

+		@Override

+		public String toString() {

+			return sb == null ? "" : String.format(sb.toString(), ao);

+		}

+	}

+

+	/**

+	 * createNS

+	 * 

+	 * Create Namespace

+	 * 

+	 * @param trans

+	 * @param org

+	 * @param ns

+	 * @param user

+	 * @return

+	 * @throws DAOException

+	 * 

+	 *             To create an NS, you need to: 1) validate permission to

+	 *             modify parent NS 2) Does NS exist already? 3) Create NS with

+	 *             a) "user" as owner. NOTE: Per 10-15 request for AAF 1.0 4)

+	 *             Loop through Roles with Parent NS, and map any that start

+	 *             with this NS into this one 5) Loop through Perms with Parent

+	 *             NS, and map any that start with this NS into this one

+	 */

+	public Result<Void> createNS(AuthzTrans trans, Namespace namespace, boolean fromApproval) {

+		Result<?> rq;

+

+		if (namespace.name.endsWith(Question.DOT_ADMIN)

+				|| namespace.name.endsWith(Question.DOT_OWNER)) {

+			return Result.err(Status.ERR_BadData,

+					"'admin' and 'owner' are reserved names in AAF");

+		}

+

+		try {

+			for (String u : namespace.owner) {

+				Organization org = trans.org();

+				Identity orgUser = org.getIdentity(trans, u);

+				if (orgUser == null || !orgUser.isResponsible()) {

+					// check if user has explicit permission

+					String reason;

+					if (org.isTestEnv() && (reason=org.validate(trans, Policy.AS_EMPLOYEE,

+							new CassExecutor(trans, this), u))!=null) {

+					    return Result.err(Status.ERR_Policy,reason);

+					}

+				}

+			}

+		} catch (Exception e) {

+			trans.error().log(e,

+					"Could not contact Organization for User Validation");

+		}

+

+		String user = trans.user();

+		// 1) May Change Parent?

+		int idx = namespace.name.lastIndexOf('.');

+		String parent;

+		if (idx < 0) {

+			if (!q.isGranted(trans, user, Define.ROOT_NS,Question.NS, ".", "create")) {

+				return Result.err(Result.ERR_Security,

+						"%s may not create Root Namespaces", user);

+			}

+			parent = null;

+			fromApproval = true;

+		} else {

+			parent = namespace.name.substring(0, idx);

+		}

+

+		if (!fromApproval) {

+			Result<NsDAO.Data> rparent = q.deriveNs(trans, parent);

+			if (rparent.notOK()) {

+				return Result.err(rparent);

+			}

+			rparent = q.mayUser(trans, user, rparent.value, Access.write);

+			if (rparent.notOK()) {

+				return Result.err(rparent);

+			}

+		}

+

+		// 2) Does requested NS exist

+		if (q.nsDAO.read(trans, namespace.name).isOKhasData()) {

+			return Result.err(Status.ERR_ConflictAlreadyExists,

+					"Target Namespace already exists");

+		}

+

+		// Someone must be responsible.

+		if (namespace.owner == null || namespace.owner.isEmpty()) {

+			return Result

+					.err(Status.ERR_Policy,

+							"Namespaces must be assigned at least one responsible party");

+		}

+

+		// 3) Create NS

+		Date now = new Date();

+

+		Result<Void> r;

+		// 3a) Admin

+

+		try {

+			// Originally, added the enterer as Admin, but that's not necessary,

+			// or helpful for Operations folks..

+			// Admins can be empty, because they can be changed by lower level

+			// NSs

+			// if(ns.admin(false).isEmpty()) {

+			// ns.admin(true).add(user);

+			// }

+			if (namespace.admin != null) {

+				for (String u : namespace.admin) {

+					if ((r = checkValidID(trans, now, u)).notOK()) {

+						return r;

+					}

+				}

+			}

+

+			// 3b) Responsible

+			Organization org = trans.org();

+			for (String u : namespace.owner) {

+				Identity orgUser = org.getIdentity(trans, u);

+				if (orgUser == null) {

+					return Result

+							.err(Status.ERR_BadData,

+									"NS must be created with an %s approved Responsible Party",

+									org.getName());

+				}

+			}

+		} catch (Exception e) {

+			return Result.err(Status.ERR_UserNotFound, e.getMessage());

+		}

+

+		// VALIDATIONS done... Add NS

+		if ((rq = q.nsDAO.create(trans, namespace.data())).notOK()) {

+		    return Result.err(rq);

+		}

+

+		// Since Namespace is now created, we need to grab all subsequent errors

+		ErrBuilder eb = new ErrBuilder();

+

+		// Add UserRole(s)

+		UserRoleDAO.Data urdd = new UserRoleDAO.Data();

+		urdd.expires = trans.org().expiration(null, Expiration.UserInRole).getTime();

+		urdd.role(namespace.name, Question.ADMIN);

+		for (String admin : namespace.admin) {

+			urdd.user = admin;

+			eb.log(q.userRoleDAO.create(trans, urdd));

+		}

+		urdd.role(namespace.name,Question.OWNER);

+		for (String owner : namespace.owner) {

+			urdd.user = owner;

+			eb.log(q.userRoleDAO.create(trans, urdd));

+		}

+

+		addNSAdminRolesPerms(trans, eb, namespace.name);

+

+		addNSOwnerRolesPerms(trans, eb, namespace.name);

+

+		if (parent != null) {

+			// Build up with any errors

+

+			Result<NsDAO.Data> parentNS = q.deriveNs(trans, parent);

+			String targetNs = parentNS.value.name; // Get the Parent Namespace,

+													// not target

+			String targetName = namespace.name.substring(parentNS.value.name.length() + 1); // Remove the Parent Namespace from the

+									// Target + a dot, and you'll get the name

+			int targetNameDot = targetName.length() + 1;

+

+			// 4) Change any roles with children matching this NS, and

+			Result<List<RoleDAO.Data>> rrdc = q.roleDAO.readChildren(trans,	targetNs, targetName);

+			if (rrdc.isOKhasData()) {

+				for (RoleDAO.Data rdd : rrdc.value) {

+					// Remove old Role from Perms, save them off

+					List<PermDAO.Data> lpdd = new ArrayList<PermDAO.Data>();

+					for(String p : rdd.perms(false)) {

+						Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans,q,p);

+						if(rpdd.isOKhasData()) {

+							PermDAO.Data pdd = rpdd.value;

+							lpdd.add(pdd);

+							q.permDAO.delRole(trans, pdd, rdd);

+						} else{

+							trans.error().log(rpdd.errorString());

+						}

+					}

+					

+					// Save off Old keys

+					String delP1 = rdd.ns;

+					String delP2 = rdd.name;

+

+					// Write in new key

+					rdd.ns = namespace.name;

+					rdd.name = (delP2.length() > targetNameDot) ? delP2

+							.substring(targetNameDot) : "";

+							

+					// Need to use non-cached, because switching namespaces, not

+					// "create" per se

+					if ((rq = q.roleDAO.create(trans, rdd)).isOK()) {

+						// Put Role back into Perm, with correct info

+						for(PermDAO.Data pdd : lpdd) {

+							q.permDAO.addRole(trans, pdd, rdd);

+						}

+						// Change data for User Roles 

+						Result<List<UserRoleDAO.Data>> rurd = q.userRoleDAO.readByRole(trans, rdd.fullName());

+						if(rurd.isOKhasData()) {

+							for(UserRoleDAO.Data urd : rurd.value) {

+								urd.ns = rdd.ns;

+								urd.rname = rdd.name;

+								q.userRoleDAO.update(trans, urd);

+							}

+						}

+						// Now delete old one

+						rdd.ns = delP1;

+						rdd.name = delP2;

+						if ((rq = q.roleDAO.delete(trans, rdd, false)).notOK()) {

+							eb.log(rq);

+						}

+					} else {

+						eb.log(rq);

+					}

+				}

+			}

+

+			// 4) Change any Permissions with children matching this NS, and

+			Result<List<PermDAO.Data>> rpdc = q.permDAO.readChildren(trans,targetNs, targetName);

+			if (rpdc.isOKhasData()) {

+				for (PermDAO.Data pdd : rpdc.value) {

+					// Remove old Perm from Roles, save them off

+					List<RoleDAO.Data> lrdd = new ArrayList<RoleDAO.Data>();

+					

+					for(String rl : pdd.roles(false)) {

+						Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,q,rl);

+						if(rrdd.isOKhasData()) {

+							RoleDAO.Data rdd = rrdd.value;

+							lrdd.add(rdd);

+							q.roleDAO.delPerm(trans, rdd, pdd);

+						} else{

+							trans.error().log(rrdd.errorString());

+						}

+					}

+					

+					// Save off Old keys

+					String delP1 = pdd.ns;

+					String delP2 = pdd.type;

+					pdd.ns = namespace.name;

+					pdd.type = (delP2.length() > targetNameDot) ? delP2

+							.substring(targetNameDot) : "";

+					if ((rq = q.permDAO.create(trans, pdd)).isOK()) {

+						// Put Role back into Perm, with correct info

+						for(RoleDAO.Data rdd : lrdd) {

+							q.roleDAO.addPerm(trans, rdd, pdd);

+						}

+

+						pdd.ns = delP1;

+						pdd.type = delP2;

+						if ((rq = q.permDAO.delete(trans, pdd, false)).notOK()) {

+							eb.log(rq);

+							// } else {

+							// Need to invalidate directly, because we're

+							// switching places in NS, not normal cache behavior

+							// q.permDAO.invalidate(trans,pdd);

+						}

+					} else {

+						eb.log(rq);

+					}

+				}

+			}

+			if (eb.hasErr()) {

+				return Result.err(Status.ERR_ActionNotCompleted,eb.sb.toString(), eb.vars());

+			}

+		}

+		return Result.ok();

+	}

+

+	private void addNSAdminRolesPerms(AuthzTrans trans, ErrBuilder eb, String ns) {

+		// Admin Role/Perm

+		RoleDAO.Data rd = new RoleDAO.Data();

+		rd.ns = ns;

+		rd.name = "admin";

+		rd.description = "AAF Namespace Administrators";

+

+		PermDAO.Data pd = new PermDAO.Data();

+		pd.ns = ns;

+		pd.type = "access";

+		pd.instance = Question.ASTERIX;

+		pd.action = Question.ASTERIX;

+		pd.description = "AAF Namespace Write Access";

+

+		rd.perms = new HashSet<String>();

+		rd.perms.add(pd.encode());

+		eb.log(q.roleDAO.create(trans, rd));

+

+		pd.roles = new HashSet<String>();

+		pd.roles.add(rd.encode());

+		eb.log(q.permDAO.create(trans, pd));

+	}

+

+	private void addNSOwnerRolesPerms(AuthzTrans trans, ErrBuilder eb, String ns) {

+		RoleDAO.Data rd = new RoleDAO.Data();

+		rd.ns = ns;

+		rd.name = "owner";

+		rd.description = "AAF Namespace Owners";

+

+		PermDAO.Data pd = new PermDAO.Data();

+		pd.ns = ns;

+		pd.type = "access";

+		pd.instance = Question.ASTERIX;

+		pd.action = Question.READ;

+		pd.description = "AAF Namespace Read Access";

+

+		rd.perms = new HashSet<String>();

+		rd.perms.add(pd.encode());

+		eb.log(q.roleDAO.create(trans, rd));

+

+		pd.roles = new HashSet<String>();

+		pd.roles.add(rd.encode());

+		eb.log(q.permDAO.create(trans, pd));

+	}

+

+	/**

+	 * deleteNS

+	 * 

+	 * Delete Namespace

+	 * 

+	 * @param trans

+	 * @param org

+	 * @param ns

+	 * @param force

+	 * @param user

+	 * @return

+	 * @throws DAOException

+	 * 

+	 * 

+	 *             To delete an NS, you need to: 1) validate permission to

+	 *             modify this NS 2) Find all Roles with this NS, and 2a) if

+	 *             Force, delete them, else modify to Parent NS 3) Find all

+	 *             Perms with this NS, and modify to Parent NS 3a) if Force,

+	 *             delete them, else modify to Parent NS 4) Find all IDs

+	 *             associated to this NS, and deny if exists. 5) Remove NS

+	 */

+	public Result<Void> deleteNS(AuthzTrans trans, String ns) {

+		boolean force = trans.forceRequested();

+		boolean move = trans.moveRequested();

+		// 1) Validate

+		Result<List<NsDAO.Data>> nsl;

+		if ((nsl = q.nsDAO.read(trans, ns)).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_NsNotFound, "%s does not exist", ns);

+		}

+		NsDAO.Data nsd = nsl.value.get(0);

+		NsType nt;

+		if (move && !q.canMove(nt = NsType.fromType(nsd.type))) {

+			return Result.err(Status.ERR_Denied, "Namespace Force=move not permitted for Type %s",nt.name());

+		}

+

+		Result<NsDAO.Data> dnr = q.mayUser(trans, trans.user(), nsd, Access.write);

+		if (dnr.status != Status.OK) {

+			return Result.err(dnr);

+		}

+

+		// 2) Find Parent

+		String user = trans.user();

+		int idx = ns.lastIndexOf('.');

+		NsDAO.Data parent;

+		if (idx < 0) {

+			if (!q.isGranted(trans, user, Define.ROOT_NS,Question.NS, ".", "delete")) {

+				return Result.err(Result.ERR_Security,

+						"%s may not delete Root Namespaces", user);

+			}

+			parent = null;

+		} else {

+			Result<NsDAO.Data> rlparent = q.deriveNs(trans,	ns.substring(0, idx));

+			if (rlparent.notOKorIsEmpty()) {

+				return Result.err(rlparent);

+			}

+			parent = rlparent.value;

+		}

+

+		// Build up with any errors

+		// If sb != null below is an indication of error

+		StringBuilder sb = null;

+		ErrBuilder er = new ErrBuilder();

+

+		// 2a) Deny if any IDs on Namespace

+		Result<List<CredDAO.Data>> creds = q.credDAO.readNS(trans, ns);

+		if (creds.isOKhasData()) {

+			if (force || move) {

+				for (CredDAO.Data cd : creds.value) {

+					er.log(q.credDAO.delete(trans, cd, false));

+					// Since we're deleting all the creds, we should delete all

+					// the user Roles for that Cred

+					Result<List<UserRoleDAO.Data>> rlurd = q.userRoleDAO

+							.readByUser(trans, cd.id);

+					if (rlurd.isOK()) {

+						for (UserRoleDAO.Data data : rlurd.value) {

+						    q.userRoleDAO.delete(trans, data, false);

+						}

+					}

+

+				}

+			} else {

+				// first possible StringBuilder Create.

+				sb = new StringBuilder();

+				sb.append('[');

+				sb.append(ns);

+				sb.append("] contains users");

+			}

+		}

+

+		// 2b) Find (or delete if forced flag is set) dependencies

+		// First, find if NS Perms are the only ones

+		Result<List<PermDAO.Data>> rpdc = q.permDAO.readNS(trans, ns);

+		if (rpdc.isOKhasData()) {

+			// Since there are now NS perms, we have to count NON-NS perms.

+			// FYI, if we delete them now, and the NS is not deleted, it is in

+			// an inconsistent state.

+			boolean nonaccess = false;

+			for (PermDAO.Data pdd : rpdc.value) {

+				if (!"access".equals(pdd.type)) {

+					nonaccess = true;

+					break;

+				}

+			}

+			if (nonaccess && !force && !move) {

+				if (sb == null) {

+					sb = new StringBuilder();

+					sb.append('[');

+					sb.append(ns);

+					sb.append("] contains ");

+				} else {

+					sb.append(", ");

+				}

+				sb.append("permissions");

+			}

+		}

+

+		Result<List<RoleDAO.Data>> rrdc = q.roleDAO.readNS(trans, ns);

+		if (rrdc.isOKhasData()) {

+			// Since there are now NS roles, we have to count NON-NS roles.

+			// FYI, if we delete th)em now, and the NS is not deleted, it is in

+			// an inconsistent state.

+			int count = rrdc.value.size();

+			for (RoleDAO.Data rdd : rrdc.value) {

+				if ("admin".equals(rdd.name) || "owner".equals(rdd.name)) {

+					--count;

+				}

+			}

+			if (count > 0 && !force && !move) {

+				if (sb == null) {

+					sb = new StringBuilder();

+					sb.append('[');

+					sb.append(ns);

+					sb.append("] contains ");

+				} else {

+					sb.append(", ");

+				}

+				sb.append("roles");

+			}

+		}

+

+		// 2c) Deny if dependencies exist that would be moved to root level

+		// parent is root level parent here. Need to find closest parent ns that

+		// exists

+		if (sb != null) {

+			if (!force && !move) {

+				sb.append(".\n  Delete dependencies and try again.  Note: using \"force=true\" will delete all. \"force=move\" will delete Creds, but move Roles and Perms to parent.");

+				return Result.err(Status.ERR_DependencyExists, sb.toString());

+			}

+

+			if (move && (parent == null || parent.type == NsType.COMPANY.type)) {

+				return Result

+						.err(Status.ERR_DependencyExists,

+								"Cannot move users, roles or permissions to [%s].\nDelete dependencies and try again",

+								parent.name);

+			}

+		} else if (move && parent != null) {

+			sb = new StringBuilder();

+			// 3) Change any roles with children matching this NS, and

+			moveRoles(trans, parent, sb, rrdc);

+			// 4) Change any Perms with children matching this NS, and

+			movePerms(trans, parent, sb, rpdc);

+		}

+

+		if (sb != null && sb.length() > 0) {

+			return Result.err(Status.ERR_DependencyExists, sb.toString());

+		}

+

+		if (er.hasErr()) {

+			if (trans.debug().isLoggable()) {

+				trans.debug().log(er.toString());

+			}

+			return Result.err(Status.ERR_DependencyExists,

+					"Namespace members cannot be deleted for %s", ns);

+		}

+

+		// 5) OK... good to go for NS Deletion...

+		if (!rpdc.isEmpty()) {

+			for (PermDAO.Data perm : rpdc.value) {

+				deletePerm(trans, perm, true, true);

+			}

+		}

+		if (!rrdc.isEmpty()) {

+			for (RoleDAO.Data role : rrdc.value) {

+				deleteRole(trans, role, true, true);

+			}

+		}

+

+		return q.nsDAO.delete(trans, nsd, false);

+	}

+

+	public Result<List<String>> getOwners(AuthzTrans trans, String ns,

+			boolean includeExpired) {

+		return getUsersByRole(trans, ns + Question.DOT_OWNER, includeExpired);

+	}

+

+	private Result<Void> mayAddOwner(AuthzTrans trans, String ns, String id) {

+		Result<NsDAO.Data> rq = q.deriveNs(trans, ns);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		rq = q.mayUser(trans, trans.user(), rq.value, Access.write);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		Identity user;

+		Organization org = trans.org();

+		try {

+			if ((user = org.getIdentity(trans, id)) == null) {

+				return Result.err(Status.ERR_Policy,

+						"%s reports that this is not a valid credential",

+						org.getName());

+			}

+			if (user.isResponsible()) {

+				return Result.ok();

+			} else {

+				String reason="This is not a Test Environment";

+				if (org.isTestEnv() && (reason = org.validate(trans, Policy.AS_EMPLOYEE, 

+						new CassExecutor(trans, this), id))==null) {

+					return Result.ok();

+				}

+				return Result.err(Status.ERR_Policy,reason);

+			}

+		} catch (Exception e) {

+			return Result.err(e);

+		}

+	}

+

+	private Result<Void> mayAddAdmin(AuthzTrans trans, String ns,	String id) {

+		// Does NS Exist?

+		Result<Void> r = checkValidID(trans, new Date(), id);

+		if (r.notOK()) {

+			return r;

+		}

+		// Is id able to be an Admin

+		Result<NsDAO.Data> rq = q.deriveNs(trans, ns);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+	

+		rq = q.mayUser(trans, trans.user(), rq.value, Access.write);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+		return r;

+	}

+

+	private Result<Void> checkValidID(AuthzTrans trans, Date now, String user) {

+		Organization org = trans.org();

+		if (user.endsWith(org.getRealm())) {

+			try {

+				if (org.getIdentity(trans, user) == null) {

+					return Result.err(Status.ERR_Denied,

+							"%s reports that %s is a faulty ID", org.getName(),

+							user);

+				}

+				return Result.ok();

+			} catch (Exception e) {

+				return Result.err(Result.ERR_Security,

+						"%s is not a valid %s Credential", user, org.getName());

+			}

+		} else {

+			Result<List<CredDAO.Data>> cdr = q.credDAO.readID(trans, user);

+			if (cdr.notOKorIsEmpty()) {

+				return Result.err(Status.ERR_Security,

+						"%s is not a valid AAF Credential", user);

+			}

+	

+			for (CredDAO.Data cd : cdr.value) {

+				if (cd.expires.after(now)) {

+					return Result.ok();

+				}

+			}

+		}

+		return Result.err(Result.ERR_Security, "%s has expired", user);

+	}

+

+	public Result<Void> delOwner(AuthzTrans trans, String ns, String id) {

+		Result<NsDAO.Data> rq = q.deriveNs(trans, ns);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		rq = q.mayUser(trans, trans.user(), rq.value, Access.write);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		return delUserRole(trans, id, ns,Question.OWNER);

+	}

+

+	public Result<List<String>> getAdmins(AuthzTrans trans, String ns, boolean includeExpired) {

+		return getUsersByRole(trans, ns + Question.DOT_ADMIN, includeExpired);

+	}

+

+	public Result<Void> delAdmin(AuthzTrans trans, String ns, String id) {

+		Result<NsDAO.Data> rq = q.deriveNs(trans, ns);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		rq = q.mayUser(trans, trans.user(), rq.value, Access.write);

+		if (rq.notOK()) {

+			return Result.err(rq);

+		}

+

+		return delUserRole(trans, id, ns, Question.ADMIN);

+	}

+

+	/**

+	 * Helper function that moves permissions from a namespace being deleted to

+	 * its parent namespace

+	 * 

+	 * @param trans

+	 * @param parent

+	 * @param sb

+	 * @param rpdc

+	 *            - list of permissions in namespace being deleted

+	 */

+	private void movePerms(AuthzTrans trans, NsDAO.Data parent,

+			StringBuilder sb, Result<List<PermDAO.Data>> rpdc) {

+

+		Result<Void> rv;

+		Result<PermDAO.Data> pd;

+

+		if (rpdc.isOKhasData()) {

+			for (PermDAO.Data pdd : rpdc.value) {

+				String delP2 = pdd.type;

+				if ("access".equals(delP2)) {

+				    continue;

+				}

+				// Remove old Perm from Roles, save them off

+				List<RoleDAO.Data> lrdd = new ArrayList<RoleDAO.Data>();

+				

+				for(String rl : pdd.roles(false)) {

+					Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,q,rl);

+					if(rrdd.isOKhasData()) {

+						RoleDAO.Data rdd = rrdd.value;

+						lrdd.add(rdd);

+						q.roleDAO.delPerm(trans, rdd, pdd);

+					} else{

+						trans.error().log(rrdd.errorString());

+					}

+				}

+				

+				// Save off Old keys

+				String delP1 = pdd.ns;

+				NsSplit nss = new NsSplit(parent, pdd.fullType());

+				pdd.ns = nss.ns;

+				pdd.type = nss.name;

+				// Use direct Create/Delete, because switching namespaces

+				if ((pd = q.permDAO.create(trans, pdd)).isOK()) {

+					// Put Role back into Perm, with correct info

+					for(RoleDAO.Data rdd : lrdd) {

+						q.roleDAO.addPerm(trans, rdd, pdd);

+					}

+

+					pdd.ns = delP1;

+					pdd.type = delP2;

+					if ((rv = q.permDAO.delete(trans, pdd, false)).notOK()) {

+						sb.append(rv.details);

+						sb.append('\n');

+						// } else {

+						// Need to invalidate directly, because we're switching

+						// places in NS, not normal cache behavior

+						// q.permDAO.invalidate(trans,pdd);

+					}

+				} else {

+					sb.append(pd.details);

+					sb.append('\n');

+				}

+			}

+		}

+	}

+

+	/**

+	 * Helper function that moves roles from a namespace being deleted to its

+	 * parent namespace

+	 * 

+	 * @param trans

+	 * @param parent

+	 * @param sb

+	 * @param rrdc

+	 *            - list of roles in namespace being deleted

+	 */

+	private void moveRoles(AuthzTrans trans, NsDAO.Data parent,

+			StringBuilder sb, Result<List<RoleDAO.Data>> rrdc) {

+

+		Result<Void> rv;

+		Result<RoleDAO.Data> rd;

+

+		if (rrdc.isOKhasData()) {

+			for (RoleDAO.Data rdd : rrdc.value) {

+				String delP2 = rdd.name;

+				if ("admin".equals(delP2) || "owner".equals(delP2)) {

+				    continue;

+				}

+				// Remove old Role from Perms, save them off

+				List<PermDAO.Data> lpdd = new ArrayList<PermDAO.Data>();

+				for(String p : rdd.perms(false)) {

+					Result<PermDAO.Data> rpdd = PermDAO.Data.decode(trans,q,p);

+					if(rpdd.isOKhasData()) {

+						PermDAO.Data pdd = rpdd.value;

+						lpdd.add(pdd);

+						q.permDAO.delRole(trans, pdd, rdd);

+					} else{

+						trans.error().log(rpdd.errorString());

+					}

+				}

+				

+				// Save off Old keys

+				String delP1 = rdd.ns;

+

+				NsSplit nss = new NsSplit(parent, rdd.fullName());

+				rdd.ns = nss.ns;

+				rdd.name = nss.name;

+				// Use direct Create/Delete, because switching namespaces

+				if ((rd = q.roleDAO.create(trans, rdd)).isOK()) {

+					// Put Role back into Perm, with correct info

+					for(PermDAO.Data pdd : lpdd) {

+						q.permDAO.addRole(trans, pdd, rdd);

+					}

+

+					rdd.ns = delP1;

+					rdd.name = delP2;

+					if ((rv = q.roleDAO.delete(trans, rdd, true)).notOK()) {

+						sb.append(rv.details);

+						sb.append('\n');

+						// } else {

+						// Need to invalidate directly, because we're switching

+						// places in NS, not normal cache behavior

+						// q.roleDAO.invalidate(trans,rdd);

+					}

+				} else {

+					sb.append(rd.details);

+					sb.append('\n');

+				}

+			}

+		}

+	}

+

+	/**

+	 * Create Permission (and any missing Permission between this and Parent) if

+	 * we have permission

+	 * 

+	 * Pass in the desired Management Permission for this Permission

+	 * 

+	 * If Force is set, then Roles listed will be created, if allowed,

+	 * pre-granted.

+	 */

+	public Result<Void> createPerm(AuthzTrans trans, PermDAO.Data perm, boolean fromApproval) {

+		String user = trans.user();

+		// Next, see if User is allowed to Manage Parent Permission

+

+		Result<NsDAO.Data> rnsd;

+		if (!fromApproval) {

+			rnsd = q.mayUser(trans, user, perm, Access.write);

+			if (rnsd.notOK()) {

+				return Result.err(rnsd);

+			}

+		} else {

+			rnsd = q.deriveNs(trans, perm.ns);

+		}

+

+		// Does Child exist?

+		if (!trans.forceRequested()) {

+			if (q.permDAO.read(trans, perm).isOKhasData()) {

+				return Result.err(Status.ERR_ConflictAlreadyExists,

+						"Permission [%s.%s|%s|%s] already exists.", perm.ns,

+						perm.type, perm.instance, perm.action);

+			}

+		}

+

+		// Attempt to add perms to roles, creating as possible

+		Set<String> roles;

+		String pstring = perm.encode();

+

+		// For each Role

+		for (String role : roles = perm.roles(true)) {

+			Result<RoleDAO.Data> rdd = RoleDAO.Data.decode(trans,q,role);

+			if(rdd.isOKhasData()) {

+				RoleDAO.Data rd = rdd.value;

+				if (!fromApproval) {

+					// May User write to the Role in question.

+					Result<NsDAO.Data> rns = q.mayUser(trans, user, rd,

+							Access.write);

+					if (rns.notOK()) {

+						// Remove the role from Add, because

+						roles.remove(role); // Don't allow adding

+						trans.warn()

+								.log("User [%s] does not have permission to relate Permissions to Role [%s]",

+										user, role);

+					}

+				}

+

+				Result<List<RoleDAO.Data>> rlrd;

+				if ((rlrd = q.roleDAO.read(trans, rd)).notOKorIsEmpty()) {

+					rd.perms(true).add(pstring);

+					if (q.roleDAO.create(trans, rd).notOK()) {

+						roles.remove(role); // Role doesn't exist, and can't be

+											// created

+					}

+				} else {

+					rd = rlrd.value.get(0);

+					if (!rd.perms.contains(pstring)) {

+						q.roleDAO.addPerm(trans, rd, perm);

+					}

+				}

+			}

+		}

+

+		Result<PermDAO.Data> pdr = q.permDAO.create(trans, perm);

+		if (pdr.isOK()) {

+			return Result.ok();

+		} else { 

+			return Result.err(pdr);

+		}

+	}

+

+	public Result<Void> deletePerm(final AuthzTrans trans, final PermDAO.Data perm, boolean force, boolean fromApproval) {

+		String user = trans.user();

+

+		// Next, see if User is allowed to Manage Permission

+		Result<NsDAO.Data> rnsd;

+		if (!fromApproval) {

+			rnsd = q.mayUser(trans, user, perm, Access.write);

+			if (rnsd.notOK()) {

+				return Result.err(rnsd);

+			}

+		}

+		// Does Perm exist?

+		Result<List<PermDAO.Data>> pdr = q.permDAO.read(trans, perm);

+		if (pdr.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound,"Permission [%s.%s|%s|%s] does not exist.",

+					perm.ns,perm.type, perm.instance, perm.action);

+		}

+		// Get perm, but with rest of data.

+		PermDAO.Data fullperm = pdr.value.get(0);

+

+		// Attached to any Roles?

+		if (fullperm.roles != null) {

+			if (force) {

+				for (String role : fullperm.roles) {

+					Result<Void> rv = null;

+					Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, q, role);

+					if(rrdd.isOKhasData()) {

+						trans.debug().log("Removing", role, "from", fullperm, "on Perm Delete");

+						if ((rv = q.roleDAO.delPerm(trans, rrdd.value, fullperm)).notOK()) {

+							if (rv.notOK()) {

+								trans.error().log("Error removing Role during delFromPermRole: ",

+												trans.getUserPrincipal(),

+												rv.errorString());

+							}

+						}

+					} else {

+						return Result.err(rrdd);

+					}

+				}

+			} else if (!fullperm.roles.isEmpty()) {

+				return Result

+						.err(Status.ERR_DependencyExists,

+								"Permission [%s.%s|%s|%s] cannot be deleted as it is attached to 1 or more roles.",

+								fullperm.ns, fullperm.type, fullperm.instance, fullperm.action);

+			}

+		}

+

+		return q.permDAO.delete(trans, fullperm, false);

+	}

+

+	public Result<Void> deleteRole(final AuthzTrans trans, final RoleDAO.Data role, boolean force, boolean fromApproval) {

+		String user = trans.user();

+

+		// Next, see if User is allowed to Manage Role

+		Result<NsDAO.Data> rnsd;

+		if (!fromApproval) {

+			rnsd = q.mayUser(trans, user, role, Access.write);

+			if (rnsd.notOK()) {

+				return Result.err(rnsd);

+			}

+		}

+

+		// Are there any Users Attached to Role?

+		Result<List<UserRoleDAO.Data>> urdr = q.userRoleDAO.readByRole(trans,role.fullName());

+		if (force) {

+			if (urdr.isOKhasData()) {

+				for (UserRoleDAO.Data urd : urdr.value) {

+					q.userRoleDAO.delete(trans, urd, false);

+				}

+			}

+		} else if (urdr.isOKhasData()) {

+			return Result.err(Status.ERR_DependencyExists,

+							"Role [%s.%s] cannot be deleted as it is used by 1 or more Users.",

+							role.ns, role.name);

+		}

+

+		// Does Role exist?

+		Result<List<RoleDAO.Data>> rdr = q.roleDAO.read(trans, role);

+		if (rdr.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound,

+					"Role [%s.%s] does not exist", role.ns, role.name);

+		}

+		RoleDAO.Data fullrole = rdr.value.get(0); // full key search

+

+		// Remove Self from Permissions... always, force or not.  Force only applies to Dependencies (Users)

+		if (fullrole.perms != null) {

+			for (String perm : fullrole.perms(false)) {

+				Result<PermDAO.Data> rpd = PermDAO.Data.decode(trans,q,perm);

+				if (rpd.isOK()) {

+					trans.debug().log("Removing", perm, "from", fullrole,"on Role Delete");

+

+					Result<?> r = q.permDAO.delRole(trans, rpd.value, fullrole);

+					if (r.notOK()) {

+						trans.error().log("ERR_FDR1 unable to remove",fullrole,"from",perm,':',r.status,'-',r.details);

+					}

+				} else {

+					trans.error().log("ERR_FDR2 Could not remove",perm,"from",fullrole);

+				}

+			}

+		}

+		return q.roleDAO.delete(trans, fullrole, false);

+	}

+

+	/**

+	 * Only owner of Permission may add to Role

+	 * 

+	 * If force set, however, Role will be created before Grant, if User is

+	 * allowed to create.

+	 * 

+	 * @param trans

+	 * @param role

+	 * @param pd

+	 * @return

+	 */

+	public Result<Void> addPermToRole(AuthzTrans trans, RoleDAO.Data role,PermDAO.Data pd, boolean fromApproval) {

+		String user = trans.user();

+		

+		if (!fromApproval) {

+			Result<NsDAO.Data> rRoleCo = q.deriveFirstNsForType(trans, role.ns, NsType.COMPANY);

+			if(rRoleCo.notOK()) {

+				return Result.err(rRoleCo);

+			}

+			Result<NsDAO.Data> rPermCo = q.deriveFirstNsForType(trans, pd.ns, NsType.COMPANY);

+			if(rPermCo.notOK()) {

+				return Result.err(rPermCo);

+			}

+

+			// Not from same company

+			if(!rRoleCo.value.name.equals(rPermCo.value.name)) {

+				Result<Data> r;

+				// Only grant if User ALSO has Write ability in Other Company

+				if((r = q.mayUser(trans, user, role, Access.write)).notOK()) {

+					return Result.err(r);

+				}

+			}

+			

+

+			// Must be Perm Admin, or Granted Special Permission

+			Result<NsDAO.Data> ucp = q.mayUser(trans, user, pd, Access.write);

+			if (ucp.notOK()) {

+				// Don't allow CLI potential Grantees to change their own AAF

+				// Perms,

+				if ((Define.ROOT_NS.equals(pd.ns) && Question.NS.equals(pd.type)) 

+						|| !q.isGranted(trans, trans.user(),Define.ROOT_NS,Question.PERM, rPermCo.value.name, "grant")) {

+				// Not otherwise granted

+				// TODO Needed?

+					return Result.err(ucp);

+				}

+				// Final Check... Don't allow Grantees to add to Roles they are

+				// part of

+				Result<List<UserRoleDAO.Data>> rlurd = q.userRoleDAO

+						.readByUser(trans, trans.user());

+				if (rlurd.isOK()) {

+					for (UserRoleDAO.Data ur : rlurd.value) {

+						if (role.ns.equals(ur.ns) && role.name.equals(ur.rname)) {

+							return Result.err(ucp);

+						}

+					}

+				}

+			}

+		}

+

+		Result<List<PermDAO.Data>> rlpd = q.permDAO.read(trans, pd);

+		if (rlpd.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound,

+					"Permission must exist to add to Role");

+		}

+

+		Result<List<RoleDAO.Data>> rlrd = q.roleDAO.read(trans, role); // Already

+																		// Checked

+																		// for

+																		// can

+																		// change

+																		// Role

+		Result<Void> rv;

+

+		if (rlrd.notOKorIsEmpty()) {

+			if (trans.forceRequested()) {

+				Result<NsDAO.Data> ucr = q.mayUser(trans, user, role,

+						Access.write);

+				if (ucr.notOK()) {

+				    return Result

+				    		.err(Status.ERR_Denied,

+				    				"Role [%s.%s] does not exist. User [%s] cannot create.",

+				    				role.ns, role.name, user);

+				}

+

+				role.perms(true).add(pd.encode());

+				Result<RoleDAO.Data> rdd = q.roleDAO.create(trans, role);

+				if (rdd.isOK()) {

+					rv = Result.ok();

+				} else {

+					rv = Result.err(rdd);

+				}

+			} else {

+			    return Result.err(Status.ERR_RoleNotFound,

+			    		"Role [%s.%s] does not exist.", role.ns, role.name);

+			}

+		} else {

+			role = rlrd.value.get(0);

+			if (role.perms(false).contains(pd.encode())) {

+				return Result.err(Status.ERR_ConflictAlreadyExists,

+								"Permission [%s.%s] is already a member of role [%s,%s]",

+								pd.ns, pd.type, role.ns, role.name);

+			}

+			role.perms(true).add(pd.encode()); // this is added for Caching

+												// access purposes... doesn't

+												// affect addPerm

+			rv = q.roleDAO.addPerm(trans, role, pd);

+		}

+		if (rv.status == Status.OK) {

+			return q.permDAO.addRole(trans, pd, role);

+			// exploring how to add information message to successful http

+			// request

+		}

+		return rv;

+	}

+

+	/**

+	 * Either Owner of Role or Permission may delete from Role

+	 * 

+	 * @param trans

+	 * @param role

+	 * @param pd

+	 * @return

+	 */

+	public Result<Void> delPermFromRole(AuthzTrans trans, RoleDAO.Data role,PermDAO.Data pd, boolean fromApproval) {

+		String user = trans.user();

+		if (!fromApproval) {

+			Result<NsDAO.Data> ucr = q.mayUser(trans, user, role, Access.write);

+			Result<NsDAO.Data> ucp = q.mayUser(trans, user, pd, Access.write);

+

+			// If Can't change either Role or Perm, then deny

+			if (ucr.notOK() && ucp.notOK()) {

+				return Result.err(Status.ERR_Denied,

+						"User [" + trans.user()

+								+ "] does not have permission to delete ["

+								+ pd.encode() + "] from Role ["

+								+ role.fullName() + ']');

+			}

+		}

+

+		Result<List<RoleDAO.Data>> rlr = q.roleDAO.read(trans, role);

+		if (rlr.notOKorIsEmpty()) {

+			// If Bad Data, clean out

+			Result<List<PermDAO.Data>> rlp = q.permDAO.read(trans, pd);

+			if (rlp.isOKhasData()) {

+				for (PermDAO.Data pv : rlp.value) {

+					q.permDAO.delRole(trans, pv, role);

+				}

+			}

+			return Result.err(rlr);

+		}

+		String perm1 = pd.encode();

+		boolean notFound;

+		if (trans.forceRequested()) {

+			notFound = false;

+		} else { // only check if force not set.

+			notFound = true;

+			for (RoleDAO.Data r : rlr.value) {

+				if (r.perms != null) {

+					for (String perm : r.perms) {

+						if (perm1.equals(perm)) {

+							notFound = false;

+							break;

+						}

+					}

+					if(!notFound) {

+						break;

+					}

+				}

+			}

+		}

+		if (notFound) { // Need to check both, in case of corruption

+			return Result.err(Status.ERR_PermissionNotFound,

+					"Permission [%s.%s|%s|%s] not associated with any Role",

+					pd.ns,pd.type,pd.instance,pd.action);

+		}

+

+		// Read Perm for full data

+		Result<List<PermDAO.Data>> rlp = q.permDAO.read(trans, pd);

+		Result<Void> rv = null;

+		if (rlp.isOKhasData()) {

+			for (PermDAO.Data pv : rlp.value) {

+				if ((rv = q.permDAO.delRole(trans, pv, role)).isOK()) {

+					if ((rv = q.roleDAO.delPerm(trans, role, pv)).notOK()) {

+						trans.error().log(

+								"Error removing Perm during delFromPermRole:",

+								trans.getUserPrincipal(), rv.errorString());

+					}

+				} else {

+					trans.error().log(

+							"Error removing Role during delFromPermRole:",

+							trans.getUserPrincipal(), rv.errorString());

+				}

+			}

+		} else {

+			rv = q.roleDAO.delPerm(trans, role, pd);

+			if (rv.notOK()) {

+				trans.error().log("Error removing Role during delFromPermRole",

+						rv.errorString());

+			}

+		}

+		return rv == null ? Result.ok() : rv;

+	}

+

+	public Result<Void> delPermFromRole(AuthzTrans trans, String role,PermDAO.Data pd) {

+		Result<NsSplit> nss = q.deriveNsSplit(trans, role);

+		if (nss.notOK()) {

+			return Result.err(nss);

+		}

+		RoleDAO.Data rd = new RoleDAO.Data();

+		rd.ns = nss.value.ns;

+		rd.name = nss.value.name;

+		return delPermFromRole(trans, rd, pd, false);

+	}

+

+	/**

+	 * Add a User to Role

+	 * 

+	 * 1) Role must exist 2) User must be a known Credential (i.e. mechID ok if

+	 * Credential) or known Organizational User

+	 * 

+	 * @param trans

+	 * @param org

+	 * @param urData

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<Void> addUserRole(AuthzTrans trans,UserRoleDAO.Data urData) {

+		Result<Void> rv;

+		if(Question.ADMIN.equals(urData.rname)) {

+			rv = mayAddAdmin(trans, urData.ns, urData.user);

+		} else if(Question.OWNER.equals(urData.rname)) {

+			rv = mayAddOwner(trans, urData.ns, urData.user);

+		} else {

+			rv = checkValidID(trans, new Date(), urData.user);

+		}

+		if(rv.notOK()) {

+			return rv; 

+		}

+		

+		// Check if record exists

+		if (q.userRoleDAO.read(trans, urData).isOKhasData()) {

+			return Result.err(Status.ERR_ConflictAlreadyExists,

+					"User Role exists");

+		}

+		if (q.roleDAO.read(trans, urData.ns, urData.rname).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound,

+					"Role [%s.%s] does not exist", urData.ns, urData.rname);

+		}

+

+		urData.expires = trans.org().expiration(null, Expiration.UserInRole, urData.user).getTime();

+		

+		

+		Result<UserRoleDAO.Data> udr = q.userRoleDAO.create(trans, urData);

+		switch (udr.status) {

+		case OK:

+			return Result.ok();

+		default:

+			return Result.err(udr);

+		}

+	}

+

+	public Result<Void> addUserRole(AuthzTrans trans, String user, String ns, String rname) {

+		UserRoleDAO.Data urdd = new UserRoleDAO.Data();

+		urdd.ns = ns;

+		urdd.role(ns, rname);

+		urdd.user = user;

+		return addUserRole(trans,urdd);

+	}

+

+	/**

+	 * Extend User Role.

+	 * 

+	 * extend the Expiration data, according to Organization rules.

+	 * 

+	 * @param trans

+	 * @param org

+	 * @param urData

+	 * @return

+	 */

+	public Result<Void> extendUserRole(AuthzTrans trans, UserRoleDAO.Data urData, boolean checkForExist) {

+		// Check if record still exists

+		if (checkForExist && q.userRoleDAO.read(trans, urData).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound,

+					"User Role does not exist");

+		}

+		if (q.roleDAO.read(trans, urData.ns, urData.rname).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound,

+					"Role [%s.%s] does not exist", urData.ns,urData.rname);

+		}

+		// Special case for "Admin" roles. Issue brought forward with Prod

+		// problem 9/26

+

+		urData.expires = trans.org().expiration(null, Expiration.UserInRole).getTime(); // get

+																				// Full

+																				// time

+																				// starting

+																				// today

+		return q.userRoleDAO.update(trans, urData);

+	}

+

+	// ////////////////////////////////////////////////////

+	// Special User Role Functions

+	// These exist, because User Roles have Expiration dates, which must be

+	// accounted for

+	// Also, as of July, 2015, Namespace Owners and Admins are now regular User

+	// Roles

+	// ////////////////////////////////////////////////////

+	public Result<List<String>> getUsersByRole(AuthzTrans trans, String role, boolean includeExpired) {

+		Result<List<UserRoleDAO.Data>> rurdd = q.userRoleDAO.readByRole(trans,role);

+		if (rurdd.notOK()) {

+			return Result.err(rurdd);

+		}

+		Date now = new Date();

+		List<UserRoleDAO.Data> list = rurdd.value;

+		List<String> rv = new ArrayList<String>(list.size()); // presize

+		for (UserRoleDAO.Data urdd : rurdd.value) {

+			if (includeExpired || urdd.expires.after(now)) {

+				rv.add(urdd.user);

+			}

+		}

+		return Result.ok(rv);

+	}

+

+	public Result<Void> delUserRole(AuthzTrans trans, String user, String ns, String rname) {

+		UserRoleDAO.Data urdd = new UserRoleDAO.Data();

+		urdd.user = user;

+		urdd.role(ns,rname);

+		Result<List<UserRoleDAO.Data>> r = q.userRoleDAO.read(trans, urdd);

+		if (r.status == 404 || r.isEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound,

+					"UserRole [%s] [%s.%s]", user, ns, rname);

+		}

+		if (r.notOK()) {

+			return Result.err(r);

+		}

+

+		return q.userRoleDAO.delete(trans, urdd, false);

+	}

+

+	public Result<List<Identity>> createFuture(AuthzTrans trans, FutureDAO.Data data, String id, String user,

+			NsDAO.Data nsd, String op) {

+		// Create Future Object

+		List<Identity> approvers=null;

+		Result<FutureDAO.Data> fr = q.futureDAO.create(trans, data, id);

+		if (fr.isOK()) {

+			// User Future ID as ticket for Approvals

+			final UUID ticket = fr.value.id;

+			ApprovalDAO.Data ad;

+			try {

+				Organization org = trans.org();

+				approvers = org.getApprovers(trans, user);

+				for (Identity u : approvers) {

+					ad = new ApprovalDAO.Data();

+					// Note ad.id is set by ApprovalDAO Create

+					ad.ticket = ticket;

+					ad.user = user;

+					ad.approver = u.id();

+					ad.status = ApprovalDAO.PENDING;

+					ad.memo = data.memo;

+					ad.type = org.getApproverType();

+					ad.operation = op;

+					// Note ad.updated is created in System

+					Result<ApprovalDAO.Data> ar = q.approvalDAO.create(trans,ad);

+					if (ar.notOK()) {

+						return Result.err(Status.ERR_ActionNotCompleted,

+								"Approval for %s, %s could not be created: %s",

+								ad.user, ad.approver, ar.details);

+					}

+				}

+				if (nsd != null) {

+					Result<List<UserRoleDAO.Data>> rrbr = q.userRoleDAO

+							.readByRole(trans, nsd.name + Question.DOT_OWNER);

+					if (rrbr.isOK()) {

+						for (UserRoleDAO.Data urd : rrbr.value) {

+							ad = new ApprovalDAO.Data();

+							// Note ad.id is set by ApprovalDAO Create

+							ad.ticket = ticket;

+							ad.user = user;

+							ad.approver = urd.user;

+							ad.status = ApprovalDAO.PENDING;

+							ad.memo = data.memo;

+							ad.type = "owner";

+							ad.operation = op;

+							// Note ad.updated is created in System

+							Result<ApprovalDAO.Data> ar = q.approvalDAO.create(trans, ad);

+							if (ar.notOK()) {

+								return Result.err(Status.ERR_ActionNotCompleted,

+												"Approval for %s, %s could not be created: %s",

+												ad.user, ad.approver,

+												ar.details);

+							}

+						}

+					}

+				}

+			} catch (Exception e) {

+				return Result.err(e);

+			}

+		}

+		

+		return Result.ok(approvers);

+	}

+

+	public Result<Void> performFutureOp(AuthzTrans trans, ApprovalDAO.Data cd) {

+		Result<List<FutureDAO.Data>> fd = q.futureDAO.read(trans, cd.ticket);

+		Result<List<ApprovalDAO.Data>> allApprovalsForTicket = q.approvalDAO

+				.readByTicket(trans, cd.ticket);

+		Result<Void> rv = Result.ok();

+		for (FutureDAO.Data curr : fd.value) {

+			if ("approved".equalsIgnoreCase(cd.status)) {

+				if (allApprovalsForTicket.value.size() <= 1) {

+					// should check if any other pendings before performing

+					// actions

+					try {

+						if (FOP_ROLE.equalsIgnoreCase(curr.target)) {

+							RoleDAO.Data data = new RoleDAO.Data();

+							data.reconstitute(curr.construct);

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								Result<RoleDAO.Data> rd;

+								if ((rd = q.roleDAO.dao().create(trans, data)).notOK()) {

+									rv = Result.err(rd);

+								}

+							} else if ("D".equalsIgnoreCase(cd.operation)) {

+								rv = deleteRole(trans, data, true, true);

+							}

+	

+						} else if (FOP_PERM.equalsIgnoreCase(curr.target)) {

+							PermDAO.Data pdd = new PermDAO.Data();

+							pdd.reconstitute(curr.construct);

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								rv = createPerm(trans, pdd, true);

+							} else if ("D".equalsIgnoreCase(cd.operation)) {

+								rv = deletePerm(trans, pdd, true, true);

+							} else if ("G".equalsIgnoreCase(cd.operation)) {

+								Set<String> roles = pdd.roles(true);

+								Result<RoleDAO.Data> rrdd = null;

+								for (String roleStr : roles) {

+									rrdd = RoleDAO.Data.decode(trans, q, roleStr);

+									if (rrdd.isOKhasData()) {

+										rv = addPermToRole(trans, rrdd.value, pdd, true);

+									} else {

+										trans.error().log(rrdd.errorString());

+									}

+								}

+							} else if ("UG".equalsIgnoreCase(cd.operation)) {

+								Set<String> roles = pdd.roles(true);

+								Result<RoleDAO.Data> rrdd;

+								for (String roleStr : roles) {

+									rrdd = RoleDAO.Data.decode(trans, q, roleStr);

+									if (rrdd.isOKhasData()) {

+										rv = delPermFromRole(trans, rrdd.value, pdd,	true);

+									} else {

+										trans.error().log(rrdd.errorString());

+									}

+								}

+							}

+	

+						} else if (FOP_USER_ROLE.equalsIgnoreCase(curr.target)) {

+							UserRoleDAO.Data data = new UserRoleDAO.Data();

+							data.reconstitute(curr.construct);

+							// if I am the last to approve, create user role

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								rv = addUserRole(trans, data);

+							} else if ("U".equals(cd.operation)) {

+								rv = extendUserRole(trans, data, true);

+							}

+	

+						} else if (FOP_NS.equalsIgnoreCase(curr.target)) {

+							Namespace namespace = new Namespace();

+							namespace.reconstitute(curr.construct);

+	

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								rv = createNS(trans, namespace, true);

+							}

+	

+						} else if (FOP_DELEGATE.equalsIgnoreCase(curr.target)) {

+							DelegateDAO.Data data = new DelegateDAO.Data();

+							data.reconstitute(curr.construct);

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								Result<DelegateDAO.Data> dd;

+								if ((dd = q.delegateDAO.create(trans, data)).notOK()) {

+									rv = Result.err(dd);

+								}

+							} else if ("U".equalsIgnoreCase(cd.operation)) {

+								rv = q.delegateDAO.update(trans, data);

+							}

+						} else if (FOP_CRED.equalsIgnoreCase(curr.target)) {

+							CredDAO.Data data = new CredDAO.Data();

+							data.reconstitute(curr.construct);

+							if ("C".equalsIgnoreCase(cd.operation)) {

+								Result<CredDAO.Data> rd;

+								if ((rd = q.credDAO.dao().create(trans, data)).notOK()) {

+									rv = Result.err(rd);

+								}

+							}

+						}

+					} catch (IOException e) {

+						trans.error().log("IOException: ", e.getMessage(),

+								" \n occurred while performing", cd.memo,

+								" from approval ", cd.id.toString());

+					}

+				}

+			} else if ("denied".equalsIgnoreCase(cd.status)) {

+				for (ApprovalDAO.Data ad : allApprovalsForTicket.value) {

+				    q.approvalDAO.delete(trans, ad, false);

+				}

+				q.futureDAO.delete(trans, curr, false);

+				if (FOP_USER_ROLE.equalsIgnoreCase(curr.target)) {

+					// if I am the last to approve, create user role

+					if ("U".equals(cd.operation)) {

+						UserRoleDAO.Data data = new UserRoleDAO.Data();

+						try {

+							data.reconstitute(curr.construct);

+						} catch (IOException e) {

+							trans.error().log("Cannot reconstitue",curr.memo);

+						}

+						rv = delUserRole(trans, data.user, data.ns, data.rname);

+					}

+				}

+

+			}

+	

+			// if I am the last to approve, delete the future object

+			if (rv.isOK() && allApprovalsForTicket.value.size() <= 1) {

+				q.futureDAO.delete(trans, curr, false);

+			}

+	

+		} // end for each

+		return rv;

+	

+	}

+

+	public Executor newExecutor(AuthzTrans trans) {

+		return new CassExecutor(trans, this);

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/PermLookup.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/PermLookup.java
new file mode 100644
index 0000000..40f5917
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/PermLookup.java
@@ -0,0 +1,184 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.hl;

+

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.TreeSet;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+

+/**

+ * PermLookup is a Storage class for the various pieces of looking up Permission 

+ * during Transactions to avoid duplicate processing

+ * 

+ *

+ */

+// Package on purpose

+class PermLookup {

+	private AuthzTrans trans;

+	private String user;

+	private Question q;

+	private Result<List<UserRoleDAO.Data>> userRoles = null;

+	private Result<List<RoleDAO.Data>> roles = null;

+	private Result<Set<String>> permNames = null;

+	private Result<List<PermDAO.Data>> perms = null;

+	

+	private PermLookup() {}

+	

+	static PermLookup get(AuthzTrans trans, Question q, String user) {

+		PermLookup lp=null;

+		Map<String, PermLookup> permMap = trans.get(Question.PERMS, null);

+		if (permMap == null) {

+			trans.put(Question.PERMS, permMap = new HashMap<String, PermLookup>());

+		} else {

+			lp = permMap.get(user);

+		}

+

+		if (lp == null) {

+			lp = new PermLookup();

+			lp.trans = trans;

+			lp.user = user;

+			lp.q = q;

+			permMap.put(user, lp);

+		}

+		return lp;

+	}

+	

+	public Result<List<UserRoleDAO.Data>> getUserRoles() {

+		if(userRoles==null) {

+			userRoles = q.userRoleDAO.readByUser(trans,user);

+			if(userRoles.isOKhasData()) {

+				List<UserRoleDAO.Data> lurdd = new ArrayList<UserRoleDAO.Data>();

+				Date now = new Date();

+				for(UserRoleDAO.Data urdd : userRoles.value) {

+					if(urdd.expires.after(now)) { // Remove Expired

+						lurdd.add(urdd);

+					}

+				}

+				if(lurdd.size()==0) {

+					return userRoles = Result.err(Status.ERR_UserNotFound,

+								"%s not found or not associated with any Roles: ",

+								user);

+				} else {

+					return userRoles = Result.ok(lurdd);

+				}

+			} else {

+				return userRoles;

+			}

+		} else {

+			return userRoles;

+		}

+	}

+

+	public Result<List<RoleDAO.Data>> getRoles() {

+		if(roles==null) {

+			Result<List<UserRoleDAO.Data>> rur = getUserRoles();

+			if(rur.isOK()) {

+				List<RoleDAO.Data> lrdd = new ArrayList<RoleDAO.Data>();

+				for (UserRoleDAO.Data urdata : rur.value) {

+					// Gather all permissions from all Roles

+					    if(urdata.ns==null || urdata.rname==null) {

+					    	trans.error().printf("DB Content Error: nulls in User Role %s %s", urdata.user,urdata.role);

+					    } else {

+							Result<List<RoleDAO.Data>> rlrd = q.roleDAO.read(

+									trans, urdata.ns, urdata.rname);

+							if(rlrd.isOK()) {

+								lrdd.addAll(rlrd.value);

+							}

+					    }

+					}

+				return roles = Result.ok(lrdd);

+			} else {

+				return roles = Result.err(rur);

+			}

+		} else {

+			return roles;

+		}

+	}

+

+	public Result<Set<String>> getPermNames() {

+		if(permNames==null) {

+			Result<List<RoleDAO.Data>> rlrd = getRoles();

+			if (rlrd.isOK()) {

+				Set<String> pns = new TreeSet<String>();

+				for (RoleDAO.Data rdata : rlrd.value) {

+					pns.addAll(rdata.perms(false));

+				}

+				return permNames = Result.ok(pns);

+			} else {

+				return permNames = Result.err(rlrd);

+			}

+		} else {

+			return permNames;

+		}

+	}

+	

+	public Result<List<PermDAO.Data>> getPerms(boolean lookup) {

+		if(perms==null) {

+			// Note: It should be ok for a Valid user to have no permissions -

+			// 8/12/2013

+			Result<Set<String>> rss = getPermNames();

+			if(rss.isOK()) {

+				List<PermDAO.Data> lpdd = new ArrayList<PermDAO.Data>();

+				for (String perm : rss.value) {

+					if(lookup) {

+						Result<String[]> ap = PermDAO.Data.decodeToArray(trans, q, perm);

+						if(ap.isOK()) {

+							Result<List<PermDAO.Data>> rlpd = q.permDAO.read(perm,trans,ap);

+							if (rlpd.isOKhasData()) {

+								for (PermDAO.Data pData : rlpd.value) {

+									lpdd.add(pData);

+								}

+							}

+						} else {

+							trans.error().log("In getPermsByUser, for", user, perm);

+						}

+					} else {

+						Result<PermDAO.Data> pr = PermDAO.Data.decode(trans, q, perm);

+						if (pr.notOK()) {

+							trans.error().log("In getPermsByUser, for", user, pr.errorString());

+						} else {

+							lpdd.add(pr.value);

+						}

+					}

+

+				}

+				return perms = Result.ok(lpdd);

+			} else {

+				return perms = Result.err(rss);

+			}

+		} else {

+			return perms;

+		}

+	}

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Question.java b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Question.java
new file mode 100644
index 0000000..c552cc9
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/aaf/hl/Question.java
@@ -0,0 +1,1087 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.hl;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.security.SecureRandom;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+import java.util.TreeSet;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.env.AuthzTransFilter;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.dao.AbsCassDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.cached.CachedCertDAO;

+import org.onap.aaf.dao.aaf.cached.CachedCredDAO;

+import org.onap.aaf.dao.aaf.cached.CachedNSDAO;

+import org.onap.aaf.dao.aaf.cached.CachedPermDAO;

+import org.onap.aaf.dao.aaf.cached.CachedRoleDAO;

+import org.onap.aaf.dao.aaf.cached.CachedUserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.CacheInfoDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.FutureDAO;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.NsSplit;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+

+import org.onap.aaf.cadi.Hash;

+import org.onap.aaf.cadi.aaf.PermEval;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.util.Chrono;

+import com.datastax.driver.core.Cluster;

+

+/**

+ * Question HL DAO

+ * 

+ * A Data Access Combination Object which asks Security and other Questions

+ * 

+ *

+ */

+public class Question {

+	// DON'T CHANGE FROM lower Case!!!

+	public static enum Type {

+		ns, role, perm, cred

+	};

+

+	public static final String OWNER="owner";

+	public static final String ADMIN="admin";

+	public static final String DOT_OWNER=".owner";

+	public static final String DOT_ADMIN=".admin";

+	static final String ASTERIX = "*";

+

+	public static enum Access {

+		read, write, create

+	};

+

+	public static final String READ = Access.read.name();

+	public static final String WRITE = Access.write.name();

+	public static final String CREATE = Access.create.name();

+

+	public static final String ROLE = Type.role.name();

+	public static final String PERM = Type.perm.name();

+	public static final String NS = Type.ns.name();

+	public static final String CRED = Type.cred.name();

+	private static final String DELG = "delg";

+	public static final String ATTRIB = "attrib";

+

+

+	public static final int MAX_SCOPE = 10;

+	public static final int APP_SCOPE = 3;

+	public static final int COMPANY_SCOPE = 2;

+	static Slot PERMS;

+

+	private static Set<String> specialLog = null;

+	public static final SecureRandom random = new SecureRandom();

+	private static long traceID = random.nextLong();

+	private static final String SPECIAL_LOG_SLOT = "SPECIAL_LOG_SLOT";

+	private static Slot specialLogSlot = null;

+	private static Slot transIDSlot = null;

+

+

+	public final HistoryDAO historyDAO;

+	public final CachedNSDAO nsDAO;

+	public final CachedRoleDAO roleDAO;

+	public final CachedPermDAO permDAO;

+	public final CachedUserRoleDAO userRoleDAO;

+	public final CachedCredDAO credDAO;

+	public final CachedCertDAO certDAO;

+	public final DelegateDAO delegateDAO;

+	public final FutureDAO futureDAO;

+	public final ApprovalDAO approvalDAO;

+	private final CacheInfoDAO cacheInfoDAO;

+

+	// final ContactDAO contDAO;

+	// private static final String DOMAIN = "@aaf.att.com";

+	// private static final int DOMAIN_LENGTH = 0;

+

+	public Question(AuthzTrans trans, Cluster cluster, String keyspace, boolean startClean) throws APIException, IOException {

+		PERMS = trans.slot("USER_PERMS");

+		trans.init().log("Instantiating DAOs");

+		historyDAO = new HistoryDAO(trans, cluster, keyspace);

+

+		// Deal with Cached Entries

+		cacheInfoDAO = new CacheInfoDAO(trans, historyDAO);

+

+		nsDAO = new CachedNSDAO(new NsDAO(trans, historyDAO, cacheInfoDAO),

+				cacheInfoDAO);

+		permDAO = new CachedPermDAO(

+				new PermDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);

+		roleDAO = new CachedRoleDAO(

+				new RoleDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);

+		userRoleDAO = new CachedUserRoleDAO(new UserRoleDAO(trans, historyDAO,

+				cacheInfoDAO), cacheInfoDAO);

+		credDAO = new CachedCredDAO(

+				new CredDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);

+		certDAO = new CachedCertDAO(

+				new CertDAO(trans, historyDAO, cacheInfoDAO), cacheInfoDAO);

+

+		futureDAO = new FutureDAO(trans, historyDAO);

+		delegateDAO = new DelegateDAO(trans, historyDAO);

+		approvalDAO = new ApprovalDAO(trans, historyDAO);

+

+		// Only want to aggressively cleanse User related Caches... The others,

+		// just normal refresh

+		if(startClean) {

+			CachedDAO.startCleansing(trans.env(), credDAO, userRoleDAO);

+			CachedDAO.startRefresh(trans.env(), cacheInfoDAO);

+		}

+		// Set a Timer to Check Caches to send messages for Caching changes

+		

+		if(specialLogSlot==null) {

+			specialLogSlot = trans.slot(SPECIAL_LOG_SLOT);

+			transIDSlot = trans.slot(AuthzTransFilter.TRANS_ID_SLOT);

+		}

+		

+		AbsCassDAO.primePSIs(trans);

+	}

+

+

+	public void close(AuthzTrans trans) {

+		historyDAO.close(trans);

+		cacheInfoDAO.close(trans);

+		nsDAO.close(trans);

+		permDAO.close(trans);

+		roleDAO.close(trans);

+		userRoleDAO.close(trans);

+		credDAO.close(trans);

+		certDAO.close(trans);

+		delegateDAO.close(trans);

+		futureDAO.close(trans);

+		approvalDAO.close(trans);

+	}

+

+	public Result<PermDAO.Data> permFrom(AuthzTrans trans, String type,

+			String instance, String action) {

+		Result<NsDAO.Data> rnd = deriveNs(trans, type);

+		if (rnd.isOK()) {

+			return Result.ok(new PermDAO.Data(new NsSplit(rnd.value, type),

+					instance, action));

+		} else {

+			return Result.err(rnd);

+		}

+	}

+

+	/**

+	 * getPermsByUser

+	 * 

+	 * Because this call is frequently called internally, AND because we already

+	 * look for it in the initial Call, we cache within the Transaction

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<List<PermDAO.Data>> getPermsByUser(AuthzTrans trans, String user, boolean lookup) {

+		return PermLookup.get(trans, this, user).getPerms(lookup);

+	}

+	

+	public Result<List<PermDAO.Data>> getPermsByUserFromRolesFilter(AuthzTrans trans, String user, String forUser) {

+		PermLookup plUser = PermLookup.get(trans, this, user);

+		Result<Set<String>> plPermNames = plUser.getPermNames();

+		if(plPermNames.notOK()) {

+			return Result.err(plPermNames);

+		}

+		

+		Set<String> nss;

+		if(forUser.equals(user)) {

+			nss = null;

+		} else {

+			// Setup a TreeSet to check on Namespaces to 

+			nss = new TreeSet<String>();

+			PermLookup fUser = PermLookup.get(trans, this, forUser);

+			Result<Set<String>> forUpn = fUser.getPermNames();

+			if(forUpn.notOK()) {

+				return Result.err(forUpn);

+			}

+			

+			for(String pn : forUpn.value) {

+				Result<String[]> decoded = PermDAO.Data.decodeToArray(trans, this, pn);

+				if(decoded.isOKhasData()) {

+					nss.add(decoded.value[0]);

+				} else {

+					trans.error().log(pn,", derived from a Role, is invalid:",decoded.errorString());

+				}

+			}

+		}

+

+		List<PermDAO.Data> rlpUser = new ArrayList<PermDAO.Data>();

+		Result<PermDAO.Data> rpdd;

+		PermDAO.Data pdd;

+		for(String pn : plPermNames.value) {

+			rpdd = PermDAO.Data.decode(trans, this, pn);

+			if(rpdd.isOKhasData()) {

+				pdd=rpdd.value;

+				if(nss==null || nss.contains(pdd.ns)) {

+					rlpUser.add(pdd);

+				}

+			} else {

+				trans.error().log(pn,", derived from a Role, is invalid.  Run Data Cleanup:",rpdd.errorString());

+			}

+		}

+		return Result.ok(rlpUser); 

+	}

+

+	public Result<List<PermDAO.Data>> getPermsByType(AuthzTrans trans, String perm) {

+		Result<NsSplit> nss = deriveNsSplit(trans, perm);

+		if (nss.notOK()) {

+			return Result.err(nss);

+		}

+		return permDAO.readByType(trans, nss.value.ns, nss.value.name);

+	}

+

+	public Result<List<PermDAO.Data>> getPermsByName(AuthzTrans trans,

+			String type, String instance, String action) {

+		Result<NsSplit> nss = deriveNsSplit(trans, type);

+		if (nss.notOK()) {

+			return Result.err(nss);

+		}

+		return permDAO.read(trans, nss.value.ns, nss.value.name, instance,action);

+	}

+

+	public Result<List<PermDAO.Data>> getPermsByRole(AuthzTrans trans, String role, boolean lookup) {

+		Result<NsSplit> nss = deriveNsSplit(trans, role);

+		if (nss.notOK()) {

+			return Result.err(nss);

+		}

+

+		Result<List<RoleDAO.Data>> rlrd = roleDAO.read(trans, nss.value.ns,

+				nss.value.name);

+		if (rlrd.notOKorIsEmpty()) {

+			return Result.err(rlrd);

+		}

+		// Using Set to avoid duplicates

+		Set<String> permNames = new HashSet<String>();

+		if (rlrd.isOKhasData()) {

+			for (RoleDAO.Data drr : rlrd.value) {

+				permNames.addAll(drr.perms(false));

+			}

+		}

+

+		// Note: It should be ok for a Valid user to have no permissions -

+		// 8/12/2013

+		List<PermDAO.Data> perms = new ArrayList<PermDAO.Data>();

+		for (String perm : permNames) {

+			Result<PermDAO.Data> pr = PermDAO.Data.decode(trans, this, perm);

+			if (pr.notOK()) {

+				return Result.err(pr);

+			}

+

+			if(lookup) {

+				Result<List<PermDAO.Data>> rlpd = permDAO.read(trans, pr.value);

+				if (rlpd.isOKhasData()) {

+					for (PermDAO.Data pData : rlpd.value) {

+						perms.add(pData);

+					}

+				}

+			} else {

+				perms.add(pr.value);

+			}

+		}

+

+		return Result.ok(perms);

+	}

+

+	public Result<List<RoleDAO.Data>> getRolesByName(AuthzTrans trans,

+			String role) {

+		Result<NsSplit> nss = deriveNsSplit(trans, role);

+		if (nss.notOK()) {

+			return Result.err(nss);

+		}

+		String r = nss.value.name;

+		if (r.endsWith(".*")) { // do children Search

+			return roleDAO.readChildren(trans, nss.value.ns,

+					r.substring(0, r.length() - 2));

+		} else if (ASTERIX.equals(r)) {

+			return roleDAO.readChildren(trans, nss.value.ns, ASTERIX);

+		} else {

+			return roleDAO.read(trans, nss.value.ns, r);

+		}

+	}

+

+	/**

+	 * Derive NS

+	 * 

+	 * Given a Child Namespace, figure out what the best Namespace parent is.

+	 * 

+	 * For instance, if in the NS table, the parent "com.att" exists, but not

+	 * "com.att.child" or "com.att.a.b.c", then passing in either

+	 * "com.att.child" or "com.att.a.b.c" will return "com.att"

+	 * 

+	 * Uses recursive search on Cached DAO data

+	 * 

+	 * @param trans

+	 * @param child

+	 * @return

+	 */

+	public Result<NsDAO.Data> deriveNs(AuthzTrans trans, String child) {

+		Result<List<NsDAO.Data>> r = nsDAO.read(trans, child);

+		

+		if (r.isOKhasData()) {

+			return Result.ok(r.value.get(0));

+		} else {

+			int dot = child == null ? -1 : child.lastIndexOf('.');

+			if (dot < 0) {

+				return Result.err(Status.ERR_NsNotFound,

+						"No Namespace for [%s]", child);

+			} else {

+				return deriveNs(trans, child.substring(0, dot));

+			}

+		}

+	}

+

+	public Result<NsDAO.Data> deriveFirstNsForType(AuthzTrans trans, String str, NsType type) {

+		NsDAO.Data nsd;

+

+		System.out.println("value of str before for loop ---------0---++++++++++++++++++" +str);

+		for(int idx = str.indexOf('.');idx>=0;idx=str.indexOf('.',idx+1)) {

+		//	System.out.println("printing value of str-----------------1------------++++++++++++++++++++++" +str);

+			Result<List<Data>> rld = nsDAO.read(trans, str.substring(0,idx));

+			System.out.println("value of idx is -----------------++++++++++++++++++++++++++" +idx);

+			System.out.println("printing value of str.substring-----------------1------------++++++++++++++++++++++" + (str.substring(0,idx)));

+			System.out.println("value of ResultListData ------------------2------------+++++++++++++++++++++++++++" +rld);

+			if(rld.isOKhasData()) {

+				System.out.println("In if loop -----------------3-------------- ++++++++++++++++");

+				System.out.println("value of nsd=rld.value.get(0).type -----------4------++++++++++++++++++++++++++++++++++++" +(nsd=rld.value.get(0)).type);

+				System.out.println("value of rld.value.get(0).name.toString()+++++++++++++++++++++++++++++++ " +rld.value.get(0).name);

+				if(type.type == (nsd=rld.value.get(0)).type) {

+					return Result.ok(nsd);

+				}

+			} else {

+				System.out.println("In else loop ----------------4------------+++++++++++++++++++++++");

+				return Result.err(Status.ERR_NsNotFound,"There is no valid Company Namespace for %s",str.substring(0,idx));

+			}

+		}

+		return Result.err(Status.ERR_NotFound, str + " does not contain type " + type.name());

+	}

+

+	public Result<NsSplit> deriveNsSplit(AuthzTrans trans, String child) {

+		Result<NsDAO.Data> ndd = deriveNs(trans, child);

+		if (ndd.isOK()) {

+			NsSplit nss = new NsSplit(ndd.value, child);

+			if (nss.isOK()) {

+				return Result.ok(nss);

+			} else {

+				return Result.err(Status.ERR_NsNotFound,

+						"Cannot split [%s] into valid namespace elements",

+						child);

+			}

+		}

+		return Result.err(ndd);

+	}

+

+	/**

+	 * Translate an ID into it's domain

+	 * 

+	 * i.e. myid1234@myapp.att.com results in domain of com.att.myapp

+	 * 

+	 * @param id

+	 * @return

+	 */

+	public static String domain2ns(String id) {

+		int at = id.indexOf('@');

+		if (at >= 0) {

+			String[] domain = id.substring(at + 1).split("\\.");

+			StringBuilder ns = new StringBuilder(id.length());

+			boolean first = true;

+			for (int i = domain.length - 1; i >= 0; --i) {

+				if (first) {

+					first = false;

+				} else {

+					ns.append('.');

+				}

+				ns.append(domain[i]);

+			}

+			return ns.toString();

+		} else {

+			return "";

+		}

+

+	}

+

+	/**

+	 * Validate Namespace of ID@Domain

+	 * 

+	 * Namespace is reverse order of Domain.

+	 * 

+	 * i.e. myid1234@myapp.att.com results in domain of com.att.myapp

+	 * 

+	 * @param trans

+	 * @param id

+	 * @return

+	 */

+	public Result<NsDAO.Data> validNSOfDomain(AuthzTrans trans, String id) {

+		// Take domain, reverse order, and check on NS

+		String ns;

+		if(id.indexOf('@')<0) { // it's already an ns, not an ID

+			ns = id;

+		} else {

+			ns = domain2ns(id);

+		}

+		if (ns.length() > 0) {

+			if(!trans.org().getDomain().equals(ns)) { 

+				Result<List<NsDAO.Data>> rlnsd = nsDAO.read(trans, ns);

+				if (rlnsd.isOKhasData()) {

+					return Result.ok(rlnsd.value.get(0));

+				}

+			}

+		}

+		return Result.err(Status.ERR_NsNotFound,

+				"A Namespace is not available for %s", id);

+	}

+

+	public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,NsDAO.Data ndd, Access access) {

+		// <ns>.access|:role:<role name>|<read|write>

+		String ns = ndd.name;

+		int last;

+		do {

+			if (isGranted(trans, user, ns, "access", ":ns", access.name())) {

+				return Result.ok(ndd);

+			}

+			if ((last = ns.lastIndexOf('.')) >= 0) {

+				ns = ns.substring(0, last);

+			}

+		} while (last >= 0);

+		// <root ns>.ns|:<client ns>:ns|<access>

+		// AAF-724 - Make consistent response for May User", and not take the

+		// last check... too confusing.

+		Result<NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, ":"	+ ndd.name + ":ns", access.name());

+		if (rv.isOK()) {

+			return rv;

+		} else if(rv.status==Result.ERR_Backend) {

+			return Result.err(rv);

+		} else {

+			return Result.err(Status.ERR_Denied, "[%s] may not %s in NS [%s]",

+					user, access.name(), ndd.name);

+		}

+	}

+

+	public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, RoleDAO.Data rdd, Access access) {

+		Result<NsDAO.Data> rnsd = deriveNs(trans, rdd.ns);

+		if (rnsd.isOK()) {

+			return mayUser(trans, user, rnsd.value, rdd, access);

+		}

+		return rnsd;

+	}

+

+	public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user, NsDAO.Data ndd, RoleDAO.Data rdd, Access access) {

+		// 1) Is User in the Role?

+		Result<List<UserRoleDAO.Data>> rurd = userRoleDAO.readUserInRole(trans, user, rdd.fullName());

+		if (rurd.isOKhasData()) {

+			return Result.ok(ndd);

+		}

+

+		String roleInst = ":role:" + rdd.name;

+		// <ns>.access|:role:<role name>|<read|write>

+		String ns = rdd.ns;

+		int last;

+		do {

+			if (isGranted(trans, user, ns,"access", roleInst, access.name())) {

+				return Result.ok(ndd);

+			}

+			if ((last = ns.lastIndexOf('.')) >= 0) {

+				ns = ns.substring(0, last);

+			}

+		} while (last >= 0);

+

+		// Check if Access by Global Role perm

+		// <root ns>.ns|:<client ns>:role:name|<access>

+		Result<NsDAO.Data> rnsd = mayUserVirtueOfNS(trans, user, ndd, ":"

+				+ rdd.ns + roleInst, access.name());

+		if (rnsd.isOK()) {

+			return rnsd;

+		} else if(rnsd.status==Result.ERR_Backend) {

+			return Result.err(rnsd);

+		}

+

+		// Check if Access to Whole NS

+		// AAF-724 - Make consistent response for May User", and not take the

+		// last check... too confusing.

+		Result<org.onap.aaf.dao.aaf.cass.NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, 

+				":" + rdd.ns + ":ns", access.name());

+		if (rv.isOK()) {

+			return rv;

+		} else if(rnsd.status==Result.ERR_Backend) {

+			return Result.err(rnsd);

+		} else {

+			return Result.err(Status.ERR_Denied, "[%s] may not %s Role [%s]",

+					user, access.name(), rdd.fullName());

+		}

+

+	}

+

+	public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,PermDAO.Data pdd, Access access) {

+		Result<NsDAO.Data> rnsd = deriveNs(trans, pdd.ns);

+		if (rnsd.isOK()) {

+			return mayUser(trans, user, rnsd.value, pdd, access);

+		}

+		return rnsd;

+	}

+

+	public Result<NsDAO.Data> mayUser(AuthzTrans trans, String user,NsDAO.Data ndd, PermDAO.Data pdd, Access access) {

+		if (isGranted(trans, user, pdd.ns, pdd.type, pdd.instance, pdd.action)) {

+			return Result.ok(ndd);

+		}

+		String permInst = ":perm:" + pdd.type + ':' + pdd.instance + ':' + pdd.action;

+		// <ns>.access|:role:<role name>|<read|write>

+		String ns = ndd.name;

+		int last;

+		do {

+			if (isGranted(trans, user, ns, "access", permInst, access.name())) {

+				return Result.ok(ndd);

+			}

+			if ((last = ns.lastIndexOf('.')) >= 0) {

+				ns = ns.substring(0, last);

+			}

+		} while (last >= 0);

+

+		// Check if Access by NS perm

+		// <root ns>.ns|:<client ns>:role:name|<access>

+		Result<NsDAO.Data> rnsd = mayUserVirtueOfNS(trans, user, ndd, ":" + pdd.ns + permInst, access.name());

+		if (rnsd.isOK()) {

+			return rnsd;

+		} else if(rnsd.status==Result.ERR_Backend) {

+			return Result.err(rnsd);

+		}

+

+		// Check if Access to Whole NS

+		// AAF-724 - Make consistent response for May User", and not take the

+		// last check... too confusing.

+		Result<NsDAO.Data> rv = mayUserVirtueOfNS(trans, user, ndd, ":"	+ pdd.ns + ":ns", access.name());

+		if (rv.isOK()) {

+			return rv;

+		} else {

+			return Result.err(Status.ERR_Denied,

+					"[%s] may not %s Perm [%s|%s|%s]", user, access.name(),

+					pdd.fullType(), pdd.instance, pdd.action);

+		}

+

+	}

+

+	public Result<Void> mayUser(AuthzTrans trans, DelegateDAO.Data dd, Access access) {

+		try {

+			boolean isUser = trans.user().equals(dd.user);

+			boolean isDelegate = dd.delegate != null

+					&& (dd.user.equals(dd.delegate) || trans.user().equals(

+							dd.delegate));

+			Organization org = trans.org();

+			switch (access) {

+			case create:

+				if (org.getIdentity(trans, dd.user) == null) {

+					return Result.err(Status.ERR_UserNotFound,

+							"[%s] is not a user in the company database.",

+							dd.user);

+				}

+				if (!dd.user.equals(dd.delegate) && org.getIdentity(trans, dd.delegate) == null) {

+					return Result.err(Status.ERR_UserNotFound,

+							"[%s] is not a user in the company database.",

+							dd.delegate);

+				}

+				if (!trans.forceRequested() && dd.user != null && dd.user.equals(dd.delegate)) {

+					return Result.err(Status.ERR_BadData,

+							"[%s] cannot be a delegate for self", dd.user);

+				}

+				if (!isUser	&& !isGranted(trans, trans.user(), Define.ROOT_NS,DELG,

+								org.getDomain(), Question.CREATE)) {

+					return Result.err(Status.ERR_Denied,

+							"[%s] may not create a delegate for [%s]",

+							trans.user(), dd.user);

+				}

+				break;

+			case read:

+			case write:

+				if (!isUser	&& !isDelegate && 

+						!isGranted(trans, trans.user(), Define.ROOT_NS,DELG,org.getDomain(), access.name())) {

+					return Result.err(Status.ERR_Denied,

+							"[%s] may not %s delegates for [%s]", trans.user(),

+							access.name(), dd.user);

+				}

+				break;

+			default:

+				return Result.err(Status.ERR_BadData,"Unknown Access type [%s]", access.name());

+			}

+		} catch (Exception e) {

+			return Result.err(e);

+		}

+		return Result.ok();

+	}

+

+	/*

+	 * Check (recursively, if necessary), if able to do something based on NS

+	 */

+	private Result<NsDAO.Data> mayUserVirtueOfNS(AuthzTrans trans, String user,	NsDAO.Data nsd, String ns_and_type, String access) {

+		String ns = nsd.name;

+

+		// If an ADMIN of the Namespace, then allow

+		

+		Result<List<UserRoleDAO.Data>> rurd;

+		if ((rurd = userRoleDAO.readUserInRole(trans, user, nsd.name+ADMIN)).isOKhasData()) {

+			return Result.ok(nsd);

+		} else if(rurd.status==Result.ERR_Backend) {

+			return Result.err(rurd);

+		}

+		

+		// If Specially granted Global Permission

+		if (isGranted(trans, user, Define.ROOT_NS,NS, ns_and_type, access)) {

+			return Result.ok(nsd);

+		}

+

+		// Check recur

+

+		int dot = ns.length();

+		if ((dot = ns.lastIndexOf('.', dot - 1)) >= 0) {

+			Result<NsDAO.Data> rnsd = deriveNs(trans, ns.substring(0, dot));

+			if (rnsd.isOK()) {

+				rnsd = mayUserVirtueOfNS(trans, user, rnsd.value, ns_and_type,access);

+			} else if(rnsd.status==Result.ERR_Backend) {

+				return Result.err(rnsd);

+			}

+			if (rnsd.isOK()) {

+				return Result.ok(nsd);

+			} else if(rnsd.status==Result.ERR_Backend) {

+				return Result.err(rnsd);

+			}

+		}

+		return Result.err(Status.ERR_Denied, "%s may not %s %s", user, access,

+				ns_and_type);

+	}

+

+	

+	/**

+	 * isGranted

+	 * 

+	 * Important function - Check internal Permission Schemes for Permission to

+	 * do things

+	 * 

+	 * @param trans

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @return

+	 */

+	public boolean isGranted(AuthzTrans trans, String user, String ns, String type,String instance, String action) {

+		Result<List<PermDAO.Data>> perms = getPermsByUser(trans, user, false);

+		if (perms.isOK()) {

+			for (PermDAO.Data pd : perms.value) {

+				if (ns.equals(pd.ns)) {

+					if (type.equals(pd.type)) {

+						if (PermEval.evalInstance(pd.instance, instance)) {

+							if(PermEval.evalAction(pd.action, action)) { // don't return action here, might miss other action 

+								return true;

+							}

+						}

+					}

+				}

+			}

+		}

+		return false;

+	}

+

+	public Result<Date> doesUserCredMatch(AuthzTrans trans, String user, byte[] cred) throws DAOException {

+		Result<List<CredDAO.Data>> result;

+		TimeTaken tt = trans.start("Read DB Cred", Env.REMOTE);

+		try {

+			result = credDAO.readID(trans, user);

+		} finally {

+			tt.done();

+		}

+

+		Result<Date> rv = null;

+		if(result.isOK()) {

+			if (result.isEmpty()) {

+				rv = Result.err(Status.ERR_UserNotFound, user);

+				if (willSpecialLog(trans,user)) {

+					trans.audit().log("Special DEBUG:", user, " does not exist in DB");

+				}

+			} else {

+				Date now = new Date();//long now = System.currentTimeMillis();

+				ByteBuffer md5=null;

+	

+				// Bug noticed 6/22. Sorting on the result can cause Concurrency Issues.	 

+				List<CredDAO.Data> cddl;

+				if(result.value.size() > 1) {

+					cddl = new ArrayList<CredDAO.Data>(result.value.size());

+					for(CredDAO.Data old : result.value) {

+						if(old.type==CredDAO.BASIC_AUTH || old.type==CredDAO.BASIC_AUTH_SHA256) {

+							cddl.add(old);

+						}

+					}

+					if(cddl.size()>1) {

+						Collections.sort(cddl,new Comparator<CredDAO.Data>() {

+							@Override

+							public int compare(org.onap.aaf.dao.aaf.cass.CredDAO.Data a,

+											   org.onap.aaf.dao.aaf.cass.CredDAO.Data b) {

+								return b.expires.compareTo(a.expires);

+							}

+						});

+					}

+				} else {

+					cddl = result.value;

+				}

+	

+				for (CredDAO.Data cdd : cddl) {

+					if (cdd.expires.after(now)) {

+						try {

+							switch(cdd.type) {

+								case CredDAO.BASIC_AUTH:

+									if(md5==null) {

+										md5=ByteBuffer.wrap(Hash.encryptMD5(cred));

+									}

+									if(md5.compareTo(cdd.cred)==0) {

+										return Result.ok(cdd.expires);

+									} else if (willSpecialLog(trans,user)) {

+										trans.audit().log("Special DEBUG:", user, "Client sent: ", trans.encryptor().encrypt(new String(cred)) ,cdd.expires);

+									}

+									break;

+								case CredDAO.BASIC_AUTH_SHA256:

+									ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + cred.length);

+									bb.putInt(cdd.other);

+									bb.put(cred);

+									byte[] hash = Hash.hashSHA256(bb.array());

+	

+									ByteBuffer sha256 = ByteBuffer.wrap(hash);

+									if(sha256.compareTo(cdd.cred)==0) {

+										return Result.ok(cdd.expires);

+									} else if (willSpecialLog(trans,user)) {

+										trans.audit().log("Special DEBUG:", user, "Client sent: ", trans.encryptor().encrypt(new String(cred)) ,cdd.expires);

+									}

+									break;

+								default:

+									trans.error().log("Unknown Credential Type %s for %s, %s",Integer.toString(cdd.type),cdd.id, Chrono.dateTime(cdd.expires));

+							}

+						} catch (NoSuchAlgorithmException e) {

+							trans.error().log(e);

+						}

+					} else {

+						rv = Result.err(Status.ERR_Security,

+								"Credentials expired " + cdd.expires.toString());

+					}

+				} // end for each

+			}

+		} else {

+			return Result.err(result);

+		}

+		return rv == null ? Result.create((Date) null, Status.ERR_Security,

+				"Wrong credential") : rv;

+	}

+

+

+	public Result<CredDAO.Data> userCredSetup(AuthzTrans trans, CredDAO.Data cred) {

+		if(cred.type==CredDAO.RAW) {

+			TimeTaken tt = trans.start("Hash Cred", Env.SUB);

+			try {

+				cred.type = CredDAO.BASIC_AUTH_SHA256;

+				cred.other = random.nextInt();

+				ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + cred.cred.capacity());

+				bb.putInt(cred.other);

+				bb.put(cred.cred);

+				byte[] hash = Hash.hashSHA256(bb.array());

+				cred.cred = ByteBuffer.wrap(hash);

+				return Result.ok(cred);

+			} catch (NoSuchAlgorithmException e) {

+				return Result.err(Status.ERR_General,e.getLocalizedMessage());

+			} finally {

+				tt.done();

+			}

+			

+		}

+		return Result.err(Status.ERR_Security,"invalid/unreadable credential");

+	}

+

+

+	public static final String APPROVED = "APPROVE";

+	public static final String REJECT = "REJECT";

+	public static final String PENDING = "PENDING";

+

+	public Result<Void> canAddUser(AuthzTrans trans, UserRoleDAO.Data data,

+			List<ApprovalDAO.Data> approvals) {

+		// get the approval policy for the organization

+

+		// get the list of approvals with an accept status

+

+		// validate the approvals against the policy

+

+		// for now check if all approvals are received and return

+		// SUCCESS/FAILURE/SKIP

+		boolean bReject = false;

+		boolean bPending = false;

+

+		for (ApprovalDAO.Data approval : approvals) {

+			if (approval.status.equals(REJECT)) {

+				bReject = true;

+			} else if (approval.status.equals(PENDING)) {

+				bPending = true;

+			}

+		}

+		if (bReject) {

+			return Result.err(Status.ERR_Policy,

+					"Approval Polocy not conformed");

+		}

+		if (bPending) {

+			return Result.err(Status.ERR_ActionNotCompleted,

+					"Required Approvals not received");

+		}

+

+		return Result.ok();

+	}

+

+	private static final String NO_CACHE_NAME = "No Cache Data named %s";

+

+	public Result<Void> clearCache(AuthzTrans trans, String cname) {

+		boolean all = "all".equals(cname);

+		Result<Void> rv = null;

+

+		if (all || NsDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, NsDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, NsDAO.TABLE, seg);

+		}

+		if (all || PermDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, PermDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, PermDAO.TABLE,seg);

+		}

+		if (all || RoleDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, RoleDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, RoleDAO.TABLE,seg);

+		}

+		if (all || UserRoleDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, UserRoleDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, UserRoleDAO.TABLE,seg);

+		}

+		if (all || CredDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, CredDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, CredDAO.TABLE,seg);

+		}

+		if (all || CertDAO.TABLE.equals(cname)) {

+			int seg[] = series(NsDAO.CACHE_SEG);

+			for(int i: seg) {cacheClear(trans, CertDAO.TABLE,i);}

+			rv = cacheInfoDAO.touch(trans, CertDAO.TABLE,seg);

+		}

+

+		if (rv == null) {

+			rv = Result.err(Status.ERR_BadData, NO_CACHE_NAME, cname);

+		}

+		return rv;

+	}

+

+	public Result<Void> cacheClear(AuthzTrans trans, String cname,Integer segment) {

+		Result<Void> rv;

+		if (NsDAO.TABLE.equals(cname)) {

+			rv = nsDAO.invalidate(segment);

+		} else if (PermDAO.TABLE.equals(cname)) {

+			rv = permDAO.invalidate(segment);

+		} else if (RoleDAO.TABLE.equals(cname)) {

+			rv = roleDAO.invalidate(segment);

+		} else if (UserRoleDAO.TABLE.equals(cname)) {

+			rv = userRoleDAO.invalidate(segment);

+		} else if (CredDAO.TABLE.equals(cname)) {

+			rv = credDAO.invalidate(segment);

+		} else if (CertDAO.TABLE.equals(cname)) {

+			rv = certDAO.invalidate(segment);

+		} else {

+			rv = Result.err(Status.ERR_BadData, NO_CACHE_NAME, cname);

+		}

+		return rv;

+	}

+

+	private int[] series(int max) {

+		int[] series = new int[max];

+		for (int i = 0; i < max; ++i)

+			series[i] = i;

+		return series;

+	}

+

+	public boolean isDelegated(AuthzTrans trans, String user, String approver) {

+		Result<List<DelegateDAO.Data>> userDelegatedFor = delegateDAO

+				.readByDelegate(trans, user);

+		for (DelegateDAO.Data curr : userDelegatedFor.value) {

+			if (curr.user.equals(approver) && curr.delegate.equals(user)

+					&& curr.expires.after(new Date())) {

+				return true;

+			}

+		}

+		return false;

+	}

+

+	public static boolean willSpecialLog(AuthzTrans trans, String user) {

+		Boolean b = trans.get(specialLogSlot, null);

+		if(b==null) {

+			if(specialLog==null) {

+				return false;

+			} else {

+				b = specialLog.contains(user);

+				trans.put(specialLogSlot, b);

+			}

+		}

+		return b;

+	}

+	

+	public static void logEncryptTrace(AuthzTrans trans, String data) {

+		long ti;

+		trans.put(transIDSlot, ti=nextTraceID());

+		trans.trace().log("id="+Long.toHexString(ti)+",data=\""+trans.env().encryptor().encrypt(data)+'"');

+	}

+

+	private synchronized static long nextTraceID() {

+		return ++traceID;

+	}

+

+	public static synchronized boolean specialLogOn(AuthzTrans trans, String id) {

+		if (specialLog == null) {

+			specialLog = new HashSet<String>();

+		}

+		boolean rc = specialLog.add(id);

+		if(rc) {

+			trans.trace().log("Trace on for",id);			

+		}

+		return rc;

+	}

+

+	public static synchronized boolean specialLogOff(AuthzTrans trans, String id) {

+		if(specialLog==null) {

+			return false;

+		}

+		boolean rv = specialLog.remove(id);

+		if (specialLog.isEmpty()) {

+			specialLog = null;

+		}

+		if(rv) {

+			trans.trace().log("Trace off for",id);

+		}

+		return rv;

+	}

+

+	/** 

+	 * canMove

+	 * Which Types can be moved

+	 * @param nsType

+	 * @return

+	 */

+	public boolean canMove(NsType nsType) {

+		boolean rv;

+		switch(nsType) {

+			case DOT:

+			case ROOT:

+			case COMPANY:

+			case UNKNOWN:

+				rv = false;

+				break;

+			default:

+				rv = true;

+		}

+		return rv;

+	}

+

+	public Result<String> isOwnerSponsor(AuthzTrans trans, String user, String ns, Identity mechID) {

+		

+		Identity caller;

+		Organization org = trans.org();

+		try {

+			caller = org.getIdentity(trans, user);

+			if(caller==null || !caller.isFound()) {

+				return Result.err(Status.ERR_NotFound,"%s is not a registered %s entity",user,org.getName());

+			}

+		} catch (Exception e) {

+			return Result.err(e);

+		}

+		String sponsor = mechID.responsibleTo();

+		Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);

+		boolean isOwner = false;

+		if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){

+			if(urdd.expires.after(new Date())) {

+				isOwner = true;

+			}

+		}};

+		if(!isOwner) {

+			return Result.err(Status.ERR_Policy,"%s is not a current owner of %s",user,ns);

+		}

+		

+		if(!caller.id().equals(sponsor)) {

+			return Result.err(Status.ERR_Denied,"%s is not the sponsor of %s",user,mechID.id());

+		}

+		return Result.ok(sponsor);

+	}

+	

+	public boolean isAdmin(AuthzTrans trans, String user, String ns) {

+		Date now = new Date();

+		Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+ADMIN);

+		if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){

+			if(urdd.expires.after(now)) {

+				return true;

+			}

+		}};

+		return false;

+	}

+	

+	public boolean isOwner(AuthzTrans trans, String user, String ns) {

+		Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);

+		Date now = new Date();

+		if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){

+			if(urdd.expires.after(now)) {

+				return true;

+			}

+		}};

+		return false;

+	}

+

+	public int countOwner(AuthzTrans trans, String user, String ns) {

+		Result<List<UserRoleDAO.Data>> rur = userRoleDAO.read(trans, user,ns+DOT_OWNER);

+		Date now = new Date();

+		int count = 0;

+		if(rur.isOKhasData()) {for(UserRoleDAO.Data urdd : rur.value){

+			if(urdd.expires.after(now)) {

+				++count;

+			}

+		}};

+		return count;

+	}

+

+}

diff --git a/authz-cass/src/main/java/org/onap/aaf/dao/session/SessionFilter.java b/authz-cass/src/main/java/org/onap/aaf/dao/session/SessionFilter.java
new file mode 100644
index 0000000..9e60443
--- /dev/null
+++ b/authz-cass/src/main/java/org/onap/aaf/dao/session/SessionFilter.java
@@ -0,0 +1,142 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.session;

+

+import java.io.IOException;

+

+import javax.servlet.Filter;

+import javax.servlet.FilterChain;

+import javax.servlet.FilterConfig;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse;

+

+import org.onap.aaf.cssa.rserv.TransFilter;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.EnvStore;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TransStore;

+import org.onap.aaf.inno.env.util.Pool;

+import org.onap.aaf.inno.env.util.Pool.Creator;

+import org.onap.aaf.inno.env.util.Pool.Pooled;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.Session;

+

+public class SessionFilter<TRANS extends TransStore> implements Filter {

+	public static final String SESSION_SLOT = "__SESSION__";

+	private static Slot sessionSlot;

+	private static Pool<Session> pool;

+

+	public SessionFilter(EnvStore<?> env, Cluster cluster, String keyspace) {

+		synchronized(env) {

+			if(sessionSlot==null) {

+				sessionSlot = env.slot(SESSION_SLOT);

+			}

+			if(pool==null) {

+				pool = new Pool<Session>(new SessionCreator(env,cluster,keyspace));

+			}

+		}

+	}

+

+	@Override

+	public void init(FilterConfig fc) throws ServletException {

+		// Session does not need any sort of configuration from Filter

+	}

+

+	@Override

+	public void doFilter(ServletRequest req, ServletResponse resp,	FilterChain chain) throws IOException, ServletException {

+		@SuppressWarnings("unchecked")

+		TRANS trans = (TRANS)req.getAttribute(TransFilter.TRANS_TAG);

+		try {

+			Pooled<Session> psess = pool.get();

+			try {

+				trans.put(sessionSlot, psess.content);

+				chain.doFilter(req, resp);

+			} finally {

+				psess.done();

+			}

+		} catch (APIException e) {

+			throw new ServletException(e);

+		}

+	}

+

+	public Pooled<Session> load(TRANS trans) throws APIException {

+		Pooled<Session> psess = pool.get();

+		trans.put(sessionSlot, psess.content);

+		return psess;

+	}

+	

+	

+	/**

+	 * Clear will drain the pool, so that new Sessions will be constructed.

+	 * 

+	 * Suitable for Management calls.	 

+	 */

+	public static void clear() {

+		if(pool!=null) {

+			pool.drain();

+		} 

+	}

+	

+	@Override

+	public void destroy() {

+		pool.drain();

+	}

+

+	private class SessionCreator implements Creator<Session> {

+		private Cluster cluster;

+		private String keyspace;

+		private Env env;

+		

+		public SessionCreator(Env env, Cluster cluster, String keyspace) {

+			this.cluster = cluster;

+			this.keyspace = keyspace;

+			this.env = env;

+		}

+		

+		@Override

+		public Session create() throws APIException {

+			env.info().log("Creating a Cassandra Session");

+			return cluster.connect(keyspace);

+		}

+

+		@Override

+		public void destroy(Session t) {

+			env.info().log("Shutting down a Cassandra Session");

+			t.close();

+		}

+

+		@Override

+		public boolean isValid(Session t) {

+			return true;

+		}

+

+		@Override

+		public void reuse(Session t) {

+			// Nothing is needed to reuse this Session

+		}

+		

+	}

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/authz/cass/hl/JU_Question.java b/authz-cass/src/test/java/org/onap/aaf/authz/cass/hl/JU_Question.java
new file mode 100644
index 0000000..86bc1ab
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/authz/cass/hl/JU_Question.java
@@ -0,0 +1,500 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cass.hl;

+

+import static junit.framework.Assert.assertEquals;

+import static junit.framework.Assert.assertFalse;

+import static junit.framework.Assert.assertTrue;

+

+import java.security.Principal;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.AfterClass;

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.onap.aaf.dao.aaf.hl.Question.Access;

+import org.onap.aaf.dao.aaf.test.AbsJUCass;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+

+public class JU_Question extends AbsJUCass {

+

+	private static final int EXPIRES_IN = 60000000;

+	private static final String COM_TEST_JU = "com.test.ju_question";

+	private static final String JU9999_JU_TEST_COM = "ju9999@ju.test.com";

+	private static final String JU9998_JU_TEST_COM = "ju9998@ju.test.com";

+	private static final String READ = "read";

+	private static final int NFR_1 = 80;

+	private static final int NFR_2 = 4000;

+	private static final int ROLE_LEVEL1 = 1000;

+	private static final int PERM_LEVEL1 = 1000;

+//	private static final int PERM_LEVEL2 = 20;

+	private static Question q;

+	private static NsDAO.Data ndd;

+

+	@BeforeClass

+	public static void startupBeforeClass() throws Exception {

+		details=false;

+		AuthzTrans trans = env.newTransNoAvg();

+		q = new Question(trans,cluster,AUTHZ, false);

+		ndd = new NsDAO.Data();

+		ndd.name=COM_TEST_JU;

+		ndd.type=3; // app

+		ndd.parent="com.test";

+		ndd.description="Temporary Namespace for JU_Question";

+		q.nsDAO.create(trans, ndd);

+	}

+	

+	@AfterClass

+	public static void endAfterClass() throws Exception {

+		q.nsDAO.delete(trans, ndd,false);

+	}

+//    @Test

+	public void mayUserRead_EmptyPerm() {

+		PermDAO.Data pdd = new PermDAO.Data();

+		Result<NsDAO.Data> result = q.mayUser(trans,JU9999_JU_TEST_COM,pdd,Access.read);

+		assertFalse(result.isOK());

+	}

+

+//    @Test

+	public void mayUserRead_OnePermNotExist() {

+		Result<NsDAO.Data> result = q.mayUser(trans,JU9999_JU_TEST_COM,newPerm(0,0,READ),Access.read);

+		assertFalse(result.isOK());

+		assertEquals("Denied - ["+ JU9999_JU_TEST_COM +"] may not read Perm [" + COM_TEST_JU + ".myPerm0|myInstance0|read]",result.errorString());

+	}

+	

+//    @Test

+	public void mayUserRead_OnePermExistDenied() {

+		PermDAO.Data perm = newPerm(0,0,READ);

+		q.permDAO.create(trans,perm);

+		try {

+			Result<NsDAO.Data> result;

+			TimeTaken tt = trans.start("q.mayUser...", Env.SUB);

+			try {

+				result = q.mayUser(trans,JU9999_JU_TEST_COM,perm,Access.read);

+			} finally {

+				tt.done();

+				assertTrue("NFR time < "+ NFR_1 + "ms",tt.millis()<NFR_1);

+			}

+			assertFalse(result.isOK());

+			assertEquals("Denied - ["+ JU9999_JU_TEST_COM +"] may not read Perm ["+COM_TEST_JU + ".myPerm0|myInstance0|read]",result.errorString());

+		} finally {

+			q.permDAO.delete(trans, perm, false);

+		}

+	}

+

+//    @Test

+	public void mayUserRead_OnePermOneRoleExistOK() {

+		PermDAO.Data perm = newPerm(0,0,READ);

+		RoleDAO.Data role = newRole(0,perm);

+		UserRoleDAO.Data ur = newUserRole(role,JU9999_JU_TEST_COM,EXPIRES_IN);

+		try {

+			q.permDAO.create(trans,perm);

+			q.roleDAO.create(trans,role);

+			q.userRoleDAO.create(trans,ur);

+			

+			Result<NsDAO.Data> result;

+			TimeTaken tt = trans.start("q.mayUser...", Env.SUB);

+			try {

+				result = q.mayUser(trans,JU9999_JU_TEST_COM,perm,Access.read);

+			} finally {

+				tt.done();

+				assertTrue("NFR time < "+ NFR_1 + "ms",tt.millis()<NFR_1);

+			}

+			assertTrue(result.isOK());

+		} finally {

+			q.permDAO.delete(trans, perm, false);

+			q.roleDAO.delete(trans, role, false);

+			q.userRoleDAO.delete(trans, ur, false);

+		}

+	}

+

+//	@Test

+	public void filter_OnePermOneRoleExistOK() {

+		PermDAO.Data perm = newPerm(0,0,READ);

+		RoleDAO.Data role = newRole(0,perm);

+		UserRoleDAO.Data ur1 = newUserRole(role,JU9998_JU_TEST_COM,EXPIRES_IN);

+		UserRoleDAO.Data ur2 = newUserRole(role,JU9999_JU_TEST_COM,EXPIRES_IN);

+		try {

+			q.permDAO.create(trans,perm);

+			q.roleDAO.create(trans,role);

+			q.userRoleDAO.create(trans,ur1);

+			q.userRoleDAO.create(trans,ur2);

+			

+			Result<List<PermDAO.Data>> pres;

+			TimeTaken tt = trans.start("q.getPerms...", Env.SUB);

+			try {

+				pres = q.getPermsByUserFromRolesFilter(trans, JU9999_JU_TEST_COM, JU9999_JU_TEST_COM);

+			} finally {

+				tt.done();

+				trans.info().log("filter_OnePermOneRleExistOK",tt);

+				assertTrue("NFR time < "+ NFR_1 + "ms",tt.millis()<NFR_1);

+			}

+			assertTrue(pres.isOK());

+			

+			try {

+				pres = q.getPermsByUserFromRolesFilter(trans, JU9999_JU_TEST_COM, JU9998_JU_TEST_COM);

+			} finally {

+				tt.done();

+				trans.info().log("filter_OnePermOneRleExistOK No Value",tt);

+				assertTrue("NFR time < "+ NFR_1 + "ms",tt.millis()<NFR_1);

+			}

+			assertFalse(pres.isOKhasData());

+

+		} finally {

+			q.permDAO.delete(trans, perm, false);

+			q.roleDAO.delete(trans, role, false);

+			q.userRoleDAO.delete(trans, ur1, false);

+			q.userRoleDAO.delete(trans, ur2, false);

+		}

+	}

+

+//    @Test

+	public void mayUserRead_OnePermMultiRoleExistOK() {

+		PermDAO.Data perm = newPerm(0,0,READ);

+		List<RoleDAO.Data> lrole = new ArrayList<RoleDAO.Data>();

+		List<UserRoleDAO.Data> lur = new ArrayList<UserRoleDAO.Data>();

+		try {

+			q.permDAO.create(trans,perm);

+			for(int i=0;i<ROLE_LEVEL1;++i) {

+				RoleDAO.Data role = newRole(i,perm);

+				lrole.add(role);

+				q.roleDAO.create(trans,role);

+				

+				UserRoleDAO.Data ur = newUserRole(role,JU9999_JU_TEST_COM,60000000);

+				lur.add(ur);

+				q.userRoleDAO.create(trans,ur);

+			}

+			

+			Result<NsDAO.Data> result;

+			TimeTaken tt = trans.start("mayUserRead_OnePermMultiRoleExistOK", Env.SUB);

+			try {

+				result = q.mayUser(trans,JU9999_JU_TEST_COM,perm,Access.read);

+			} finally {

+				tt.done();

+				env.info().log(tt,ROLE_LEVEL1,"iterations");

+				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+			}

+			assertTrue(result.isOK());

+		} finally {

+			q.permDAO.delete(trans, perm, false);

+			for(RoleDAO.Data role : lrole) {

+				q.roleDAO.delete(trans, role, false);

+			}

+			for(UserRoleDAO.Data ur : lur) {

+				q.userRoleDAO.delete(trans, ur, false);

+			}

+		}

+	}

+

+    @Test

+	public void mayUserRead_MultiPermOneRoleExistOK() {

+		RoleDAO.Data role = newRole(0);

+		UserRoleDAO.Data ur = newUserRole(role,JU9999_JU_TEST_COM,EXPIRES_IN);

+		List<PermDAO.Data> lperm = new ArrayList<PermDAO.Data>();

+		try {

+			for(int i=0;i<PERM_LEVEL1;++i) {

+				lperm.add(newPerm(i,i,READ,role));

+			}

+			q.roleDAO.create(trans, role);

+			q.userRoleDAO.create(trans, ur);

+			

+			Result<NsDAO.Data> result;

+			TimeTaken tt = trans.start("mayUserRead_MultiPermOneRoleExistOK", Env.SUB);

+			try {

+				result = q.mayUser(trans,JU9999_JU_TEST_COM,lperm.get(PERM_LEVEL1-1),Access.read);

+			} finally {

+				tt.done();

+				env.info().log(tt,PERM_LEVEL1,"iterations");

+				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+			}

+			assertTrue(result.isOK());

+		} finally {

+			for(PermDAO.Data perm : lperm) {

+				q.permDAO.delete(trans, perm, false);

+			}

+			q.roleDAO.delete(trans, role, false);

+			q.userRoleDAO.delete(trans, ur, false);

+		}

+	}

+

+////	@Test

+//	public void mayUserRead_MultiPermMultiRoleExistOK() {

+//		List<PermDAO.Data> lperm = new ArrayList<PermDAO.Data>();

+//		List<RoleDAO.Data> lrole = new ArrayList<RoleDAO.Data>();

+//		List<UserRoleDAO.Data> lur = new ArrayList<UserRoleDAO.Data>();

+//

+//		try {

+//			RoleDAO.Data role;

+//			UserRoleDAO.Data ur;

+//			for(int i=0;i<ROLE_LEVEL1;++i) {

+//				lrole.add(role=newRole(i));

+//				q.roleDAO.create(trans, role);

+//				lur.add(ur=newUserRole(role, JU9999_JU_TEST_COM, EXPIRES_IN));

+//				q.userRoleDAO.create(trans, ur);

+//				for(int j=0;j<PERM_LEVEL2;++j) {

+//					lperm.add(newPerm(i,j,READ,role));

+//				}

+//			}

+//			

+//			Result<NsDAO.Data> result;

+//			TimeTaken tt = trans.start("mayUserRead_MultiPermMultiRoleExistOK", Env.SUB);

+//			try {

+//				result = q.mayUser(trans,JU9999_JU_TEST_COM,lperm.get(ROLE_LEVEL1*PERM_LEVEL2-1),Access.read);

+//			} finally {

+//				tt.done();

+//				env.info().log(tt,lperm.size(),"perms",", ",lrole.size(),"role");

+//				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+//			}

+//			assertTrue(result.isOK());

+//		} finally {

+//			for(PermDAO.Data perm : lperm) {

+//				q.permDAO.delete(trans, perm, false);

+//			}

+//			for(RoleDAO.Data role : lrole) {

+//				q.roleDAO.delete(trans, role, false);

+//			}

+//			for(UserRoleDAO.Data ur : lur) {

+//				q.userRoleDAO.delete(trans, ur, false);

+//			}

+//		}

+//	}

+

+	@Test

+	public void mayUserRead_MultiPermMultiRoleExist_10x10() {

+		env.info().log("Original Filter Method 10x10");

+		mayUserRead_MultiPermMultiRoleExist(10,10);

+		env.info().log("New Filter Method 10x10");

+		mayUserRead_MultiPermMultiRoleExist_NewOK(10,10);

+	}

+

+//	@Test

+	public void mayUserRead_MultiPermMultiRoleExist_20x10() {

+		env.info().log("mayUserRead_MultiPermMultiRoleExist_20x10");

+		mayUserRead_MultiPermMultiRoleExist_NewOK(20,10);

+	}

+

+//	@Test

+	public void mayUserRead_MultiPermMultiRoleExist_100x10() {

+		env.info().log("mayUserRead_MultiPermMultiRoleExist_100x10");

+		mayUserRead_MultiPermMultiRoleExist_NewOK(100,10);

+	}

+

+//	@Test

+	public void mayUserRead_MultiPermMultiRoleExist_100x20() {

+		env.info().log("mayUserRead_MultiPermMultiRoleExist_100x20");

+		mayUserRead_MultiPermMultiRoleExist_NewOK(100,20);

+	}

+

+//	@Test

+	public void mayUserRead_MultiPermMultiRoleExist_1000x20() {

+		env.info().log("mayUserRead_MultiPermMultiRoleExist_1000x20");

+		mayUserRead_MultiPermMultiRoleExist_NewOK(1000,20);

+	}

+

+	private void mayUserRead_MultiPermMultiRoleExist(int roleLevel, int permLevel) {

+		List<PermDAO.Data> lperm = new ArrayList<PermDAO.Data>();

+		List<RoleDAO.Data> lrole = new ArrayList<RoleDAO.Data>();

+		List<UserRoleDAO.Data> lur = new ArrayList<UserRoleDAO.Data>();

+		load(roleLevel, permLevel, lperm,lrole,lur);

+

+

+		Result<List<PermDAO.Data>> pres;

+		trans.setUser(new Principal() {

+			@Override

+			public String getName() {

+				return JU9999_JU_TEST_COM;

+			}

+		});

+

+		try {

+			TimeTaken group = trans.start("  Original Security Method (1st time)", Env.SUB);

+			try {

+				TimeTaken tt = trans.start("    Get User Perms for "+JU9998_JU_TEST_COM, Env.SUB);

+				try {

+					pres = q.getPermsByUser(trans,JU9998_JU_TEST_COM,true);

+				} finally {

+					tt.done();

+					env.info().log(tt,"  Looked up (full) getPermsByUser for",JU9998_JU_TEST_COM);

+				}

+				assertTrue(pres.isOK());

+				tt = trans.start("    q.mayUser", Env.SUB);

+				List<PermDAO.Data> reduced = new ArrayList<PermDAO.Data>();

+				

+				try {

+					for(PermDAO.Data p : pres.value) {

+						Result<Data> r = q.mayUser(trans,JU9999_JU_TEST_COM,p,Access.read);

+						if(r.isOK()) {

+							reduced.add(p);

+						}

+					}

+				} finally {

+					tt.done();

+					env.info().log(tt," reduced" + pres.value.size(),"perms","to",reduced.size());

+	//				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+				}

+	//			assertFalse(result.isOK());

+			} finally {

+				group.done();

+				env.info().log(group,"  Original Validation Method (1st pass)");

+			}

+			

+

+		} finally {

+			unload(lperm, lrole, lur);

+		}

+	}

+

+	private void mayUserRead_MultiPermMultiRoleExist_NewOK(int roleLevel, int permLevel) {

+		List<PermDAO.Data> lperm = new ArrayList<PermDAO.Data>();

+		List<RoleDAO.Data> lrole = new ArrayList<RoleDAO.Data>();

+		List<UserRoleDAO.Data> lur = new ArrayList<UserRoleDAO.Data>();

+		load(roleLevel, permLevel, lperm,lrole,lur);

+

+		try {

+

+			Result<List<PermDAO.Data>> pres;

+			TimeTaken tt = trans.start("  mayUserRead_MultiPermMultiRoleExist_New New Filter", Env.SUB);

+			try {

+				pres = q.getPermsByUserFromRolesFilter(trans, JU9999_JU_TEST_COM, JU9998_JU_TEST_COM);

+			} finally {

+				tt.done();

+				env.info().log(tt,lperm.size(),"perms",", ",lrole.size(),"role", lur.size(), "UserRoles");

+//				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+			}

+//			assertTrue(pres.isOKhasData());

+

+			tt = trans.start("  mayUserRead_MultiPermMultiRoleExist_New New Filter (2nd time)", Env.SUB);

+			try {

+				pres = q.getPermsByUserFromRolesFilter(trans, JU9999_JU_TEST_COM, JU9998_JU_TEST_COM);

+			} finally {

+				tt.done();

+				env.info().log(tt,lperm.size(),"perms",", ",lrole.size(),"role", lur.size(), "UserRoles");

+				assertTrue("NFR time < "+ NFR_2 + "ms",tt.millis()<NFR_2);

+			}

+//			assertTrue(pres.isOKhasData());

+

+		} finally {

+			unload(lperm, lrole, lur);

+		}

+	}

+

+

+	private void load(int roleLevel, int permLevel,	List<PermDAO.Data> lperm , List<RoleDAO.Data> lrole, List<UserRoleDAO.Data> lur) {

+		RoleDAO.Data role;

+		UserRoleDAO.Data ur;

+		PermDAO.Data perm;

+		

+		int onethirdR=roleLevel/3;

+		int twothirdR=onethirdR*2;

+		int onethirdP=permLevel/3;

+		int twothirdP=onethirdP*2;

+

+		for(int i=0;i<roleLevel;++i) {

+			lrole.add(role=newRole(i));

+			if(i<onethirdR) { // one has

+				lur.add(ur=newUserRole(role, JU9998_JU_TEST_COM, EXPIRES_IN));

+				q.userRoleDAO.create(trans, ur);

+				for(int j=0;j<onethirdP;++j) {

+					lperm.add(perm=newPerm(i,j,READ,role));

+					q.permDAO.create(trans, perm);

+				}

+			} else if(i<twothirdR) { // both have

+				lur.add(ur=newUserRole(role, JU9998_JU_TEST_COM, EXPIRES_IN));

+				q.userRoleDAO.create(trans, ur);

+				lur.add(ur=newUserRole(role, JU9999_JU_TEST_COM, EXPIRES_IN));

+				q.userRoleDAO.create(trans, ur);

+				for(int j=onethirdP;j<twothirdP;++j) {

+					lperm.add(perm=newPerm(i,j,READ,role));

+					q.permDAO.create(trans, perm);

+				}

+			} else { // other has

+				lur.add(ur=newUserRole(role, JU9999_JU_TEST_COM, EXPIRES_IN));

+				q.userRoleDAO.create(trans, ur);

+				for(int j=twothirdP;j<permLevel;++j) {

+					lperm.add(perm=newPerm(i,j,READ,role));

+					q.permDAO.create(trans, perm);

+				}

+			}

+			q.roleDAO.create(trans, role);

+		}

+

+	}

+	

+	private void unload(List<PermDAO.Data> lperm , List<RoleDAO.Data> lrole, List<UserRoleDAO.Data> lur) {

+		for(PermDAO.Data perm : lperm) {

+			q.permDAO.delete(trans, perm, false);

+		}

+		for(RoleDAO.Data role : lrole) {

+			q.roleDAO.delete(trans, role, false);

+		}

+		for(UserRoleDAO.Data ur : lur) {

+			q.userRoleDAO.delete(trans, ur, false);

+		}

+

+	}

+	private PermDAO.Data newPerm(int permNum, int instNum, String action, RoleDAO.Data ... grant) {

+		PermDAO.Data pdd = new PermDAO.Data();

+		pdd.ns=COM_TEST_JU;

+		pdd.type="myPerm"+permNum;

+		pdd.instance="myInstance"+instNum;

+		pdd.action=action;

+		for(RoleDAO.Data r : grant) {

+			pdd.roles(true).add(r.fullName());

+			r.perms(true).add(pdd.encode());

+		}

+		return pdd;

+	}

+

+	private RoleDAO.Data newRole(int roleNum, PermDAO.Data ... grant) {

+		RoleDAO.Data rdd = new RoleDAO.Data();

+		rdd.ns = COM_TEST_JU+roleNum;

+		rdd.name = "myRole"+roleNum;

+		for(PermDAO.Data p : grant) {

+			rdd.perms(true).add(p.encode());

+			p.roles(true).add(rdd.fullName());

+		}

+		return rdd;

+	}

+

+	private UserRoleDAO.Data newUserRole(RoleDAO.Data role,String user, long offset) {

+		UserRoleDAO.Data urd = new UserRoleDAO.Data();

+		urd.user=user;

+		urd.role(role);

+		urd.expires=new Date(System.currentTimeMillis()+offset);

+		return urd;

+	}

+

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/JU_Cached.java b/authz-cass/src/test/java/org/onap/aaf/dao/JU_Cached.java
new file mode 100644
index 0000000..aa0785a
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/JU_Cached.java
@@ -0,0 +1,127 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import static org.junit.Assert.*;

+

+import java.util.Date;

+import java.util.List;

+import java.util.Map;

+import java.util.Timer;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cache.Cache;

+import org.onap.aaf.cache.Cache.Dated;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.Cached;

+import org.onap.aaf.dao.Cached.Getter;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+//import org.onap.aaf.dao.Cached.Refresh;

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(PowerMockRunner.class)

+public class JU_Cached {

+	Cached cached;

+	@Mock

+	CIDAO<Trans> ciDaoMock;

+	@Mock

+	AuthzEnv authzEnvMock;

+	@Mock

+	CIDAO<AuthzTrans> cidaoATMock;

+	

+	String name = "nameString";

+	

+	@Before

+	public void setUp(){

+		cached = new Cached(ciDaoMock, name, 0);

+	}

+	

+	@Test(expected=ArithmeticException.class)

+	public void testCachedIdx(){

+		int Result = cached.cacheIdx("1234567890");		

+	}

+	

+	@Test(expected=ArithmeticException.class)

+	public void testInvalidate(){

+		int Res = cached.invalidate(name);

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testStopTimer(){

+		cached.stopTimer();

+		assertTrue(true);

+	}

+

+	@SuppressWarnings("static-access")

+	@Test

+	public void testStartRefresh(){

+		cached.startRefresh(authzEnvMock, cidaoATMock);

+		assertTrue(true);

+	}

+//	@Mock

+//	Trans transMock;

+//	@Mock

+//	Getter<DAO> getterMock;

+//	

+//	@Test

+//	public void testGet(){

+//		cached.get(transMock, name, getterMock);

+//		fail("not implemented");

+//	}

+//	

+//	@SuppressWarnings("unchecked")

+//	public Result<List<DATA>> get(TRANS trans, String key, Getter<DATA> getter) {

+//		List<DATA> ld = null;

+//		Result<List<DATA>> rld = null;

+//		

+//		int cacheIdx = cacheIdx(key);

+//		Map<String, Dated> map = ((Map<String,Dated>)cache[cacheIdx]);

+//		

+//		// Check for saved element in cache

+//		Dated cached = map.get(key);

+//		// Note: These Segment Timestamps are kept up to date with DB

+//		Date dbStamp = info.get(trans, name,cacheIdx);

+//		

+//		// Check for cache Entry and whether it is still good (a good Cache Entry is same or after DBEntry, so we use "before" syntax)

+//		if(cached!=null && dbStamp.before(cached.timestamp)) {

+//			ld = (List<DATA>)cached.data;

+//			rld = Result.ok(ld);

+//		} else {

+//			rld = getter.get();

+//			if(rld.isOK()) { // only store valid lists

+//				map.put(key, new Dated(rld.value));  // successful item found gets put in cache

+////			} else if(rld.status == Result.ERR_Backend){

+////				map.remove(key);

+//			}

+//		}

+//		return rld;

+//	}

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/JU_CachedDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CachedDAO.java
new file mode 100644
index 0000000..3bb78d2
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CachedDAO.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import static org.junit.Assert.*;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.CachedDAO;

+import org.onap.aaf.dao.DAO;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(PowerMockRunner.class)

+public class JU_CachedDAO {

+	CachedDAO cachedDAO;

+	@Mock

+	DAO daoMock;

+	@Mock

+	CIDAO<Trans> ciDAOMock; 

+	int segsize=1;

+	Object[ ] objs = new Object[2];

+	

+	@Before

+	public void setUp(){

+		objs[0] = "helo";

+		objs[1] = "polo";

+		cachedDAO = new CachedDAO(daoMock, ciDAOMock, segsize);

+	}

+		

+	@Test

+	public void testKeyFromObjs(){

+		String result = cachedDAO.keyFromObjs(objs);

+		System.out.println("value of resut " +result);

+		assertTrue(true);

+	}

+	

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassAccess.java b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassAccess.java
new file mode 100644
index 0000000..41443fb
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassAccess.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.dao.CassAccess;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+//import org.onap.aaf.dao.CassAccess.Resettable;

+import com.datastax.driver.core.Cluster.Builder;

+

+@RunWith(PowerMockRunner.class)

+public class JU_CassAccess {

+	CassAccess cassAccess;

+	

+	public static final String KEYSPACE = "authz";

+	public static final String CASSANDRA_CLUSTERS = "cassandra.clusters";

+	public static final String CASSANDRA_CLUSTERS_PORT = "cassandra.clusters.port";

+	public static final String CASSANDRA_CLUSTERS_USER_NAME = "cassandra.clusters.user";

+	public static final String CASSANDRA_CLUSTERS_PASSWORD = "cassandra.clusters.password";

+	public static final String CASSANDRA_RESET_EXCEPTIONS = "cassandra.reset.exceptions";

+	public static final String LATITUDE = "LATITUDE";

+	public static final String LONGITUDE = "LONGITUDE";

+	//private static final List<Resettable> resetExceptions = new ArrayList<Resettable>();

+	public static final String ERR_ACCESS_MSG = "Accessing Backend";

+	private static Builder cb = null;

+	@Mock

+	Env envMock;

+	String prefix=null;

+	

+	@Before

+	public void setUp(){

+		cassAccess = new CassAccess();

+	}

+

+

+	@Test(expected=APIException.class)

+	public void testCluster() throws APIException, IOException {

+		cassAccess.cluster(envMock, prefix);

+		

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassDAOImpl.java b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassDAOImpl.java
new file mode 100644
index 0000000..34106e2
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/JU_CassDAOImpl.java
@@ -0,0 +1,97 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.dao.CassDAOImpl;

+import org.onap.aaf.dao.Loader;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Trans;

+import org.onap.aaf.inno.env.TransStore;

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ConsistencyLevel;

+

+@RunWith(PowerMockRunner.class)

+public class JU_CassDAOImpl {

+

+public static final String CASS_READ_CONSISTENCY="cassandra.readConsistency";

+public static final String CASS_WRITE_CONSISTENCY="cassandra.writeConsistency";

+

+CassDAOImpl cassDAOImpl;

+

+

+@Mock

+TransStore transStoreMock;

+@SuppressWarnings("rawtypes")

+Class dcMock;

+@SuppressWarnings("rawtypes")

+Loader loaderMock;

+Cluster clusterMock;

+Class<Data> classDataMock;

+ConsistencyLevel consistencyLevelMock;

+Trans transMock;

+

+@Mock

+AuthzTrans authzTransMock;

+

+

+

+	@SuppressWarnings({ "rawtypes", "unchecked" })

+	@Before

+	public void setUp()

+	{

+		String name = "name";

+		String keySpace = "keySpace";

+		String table = "table";

+		cassDAOImpl = new CassDAOImpl(transStoreMock, name, clusterMock, keySpace, classDataMock, table, consistencyLevelMock, consistencyLevelMock);

+	}

+

+	

+	@Test 

+	public void testReadConsistency() {

+		String table = "users";

+		PowerMockito.when(authzTransMock.getProperty(CASS_READ_CONSISTENCY+'.'+table)).thenReturn("TWO");

+		ConsistencyLevel consistencyLevel = cassDAOImpl.readConsistency(authzTransMock, table);

+		System.out.println("Consistency level" + consistencyLevel.name());

+		assertEquals("TWO", consistencyLevel.name());

+	}

+	

+	@Test 

+	public void testWriteConsistency() {

+		String table = "users";

+		PowerMockito.when(authzTransMock.getProperty(CASS_WRITE_CONSISTENCY+'.'+table)).thenReturn(null);

+		ConsistencyLevel consistencyLevel = cassDAOImpl.writeConsistency(authzTransMock, table);

+		System.out.println("Consistency level" + consistencyLevel.name());

+		assertEquals("ONE", consistencyLevel.name());

+	}

+	

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/JU_DAOException.java b/authz-cass/src/test/java/org/onap/aaf/dao/JU_DAOException.java
new file mode 100644
index 0000000..4c3b11c
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/JU_DAOException.java
@@ -0,0 +1,50 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.onap.aaf.dao.DAOException;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_DAOException {

+DAOException daoException;

+

+	//DAOException daoException = new DAOException();

+	String message = "message";

+	Throwable cause;	

+	@Before

+	public void setUp(){

+	daoException = new DAOException();	

+	}

+

+	@Test

+	public void test(){

+		assertTrue(true);

+	}

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/AbsJUCass.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/AbsJUCass.java
new file mode 100644
index 0000000..887f88b
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/AbsJUCass.java
@@ -0,0 +1,200 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.URL;

+import java.security.NoSuchAlgorithmException;

+import java.util.Properties;

+

+import org.junit.After;

+import org.junit.AfterClass;

+import org.junit.Before;

+import org.junit.BeforeClass;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.CassDAOImpl;

+

+import org.onap.aaf.cadi.Hash;

+import org.onap.aaf.cadi.Symm;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Trans.Metric;

+import com.datastax.driver.core.Cluster;

+

+import junit.framework.Assert;

+

+/**

+ * Do Setup of Cassandra for Cassandra JUnit Testing

+ * 

+ *

+ */

+public class AbsJUCass {

+	protected static final String AUTHZ = "authz";

+	protected static Cluster cluster;

+	protected static AuthzEnv env;

+	protected static int iterations = 0;

+	protected static float totals=0.0f;

+	protected static float remote = 0.0f;

+	protected static float json = 0.0f;

+	protected static AuthzTrans trans;

+	protected static boolean details = true;

+	

+	@BeforeClass 

+	public static void startup() throws APIException, IOException {

+		synchronized(AUTHZ) {

+			if(env==null) {

+				final String resource = "cadi.properties";

+	            File f = new File("etc" + resource);

+	            InputStream is=null;

+	            Properties props = new Properties();

+	            try {

+	                if(f.exists()) {

+	                    is = new FileInputStream(f);

+	                } else {

+	                    URL rsrc = ClassLoader.getSystemResource(resource);

+	                    is = rsrc.openStream();

+	                }

+	                props.load(is);

+	            } finally {

+	                if(is==null) {

+	                	env= new AuthzEnv();

+	                    Assert.fail(resource + " must exist in etc dir, or in Classpath");

+	                }

+	                is.close();

+	            }

+				env = new AuthzEnv(props);

+			}

+		}

+		cluster = CassAccess.cluster(env,"LOCAL");

+

+		env.info().log("Connecting to Cluster");

+		try {

+			cluster.connect(AUTHZ);

+		} catch(Exception e) {

+			cluster=null;

+			env.error().log(e);

+			Assert.fail("Not able to connect to DB: " + e.getLocalizedMessage());

+		}

+		env.info().log("Connected");

+		

+		// Load special data here

+		

+		// WebPhone

+		env.setProperty("java.naming.provider.url","ldap://ldap.webphone.att.com:389");

+		env.setProperty("com.sun.jndi.ldap.connect.pool","true");

+		

+		iterations = 0;

+		

+	}

+	

+	@AfterClass

+	public static void shutdown() {

+		if(cluster!=null) {

+			cluster.close();

+			cluster = null;

+		}

+	}

+

+	@Before

+	public void newTrans() {

+		trans = env.newTrans();

+		

+		trans.setProperty(CassDAOImpl.USER_NAME, System.getProperty("user.name"));

+	}

+	

+	@After

+	public void auditTrail() {

+		if(totals==0) { // "updateTotals()" was not called... just do one Trans

+			StringBuilder sb = new StringBuilder();

+			Metric metric = trans.auditTrail(4, sb, Env.JSON, Env.REMOTE);

+			if(details) {

+				env.info().log(

+				sb,

+				"Total time:",

+				totals += metric.total,

+				"JSON time: ",

+				metric.buckets[0],

+				"REMOTE time: ",

+				metric.buckets[1]

+				);

+			} else {

+				totals += metric.total;

+			}

+		}

+	}

+	

+	protected void updateTotals() {

+		Metric metric = trans.auditTrail(0, null, Env.JSON, Env.REMOTE);

+		totals+=metric.total;

+		json  +=metric.buckets[0];

+		remote+=metric.buckets[1];

+	}

+

+

+	@AfterClass

+	public static void print() {

+		float transTime;

+		if(iterations==0) {

+			transTime=totals;

+		} else {

+			transTime=totals/iterations;

+		}

+		env.info().log(

+		"Total time:",

+		totals,   

+		"JSON time:",

+		json,

+		"REMOTE time:",

+		remote,

+		"Iterations:",

+		iterations,

+		"Transaction time:",

+		transTime

+		);

+	}

+	

+	/**

+	 * Take a User/Pass and turn into an MD5 Hashed BasicAuth

+	 * 

+	 * @param user

+	 * @param pass

+	 * @return

+	 * @throws IOException

+	 * @throws NoSuchAlgorithmException

+	 */

+	public static byte[] userPassToBytes(String user, String pass)

+			throws IOException, NoSuchAlgorithmException {

+		// Take the form of BasicAuth, so as to allow any character in Password

+		// (this is an issue in 1.0)

+		// Also, it makes it quicker to evaluate Basic Auth direct questions

+		String ba = Symm.base64url.encode(user + ':' + pass);

+		// Take MD5 Hash, so that data in DB can't be reversed out.

+		return Hash.encryptMD5(ba.getBytes());

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ApprovalDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ApprovalDAO.java
new file mode 100644
index 0000000..46720c3
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ApprovalDAO.java
@@ -0,0 +1,147 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotSame;

+import static org.junit.Assert.assertTrue;

+

+import java.util.Date;

+import java.util.List;

+import java.util.UUID;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO.Data;

+

+public class JU_ApprovalDAO  extends AbsJUCass {

+	@Test

+	public void testCRUD() throws Exception {

+		ApprovalDAO rrDAO = new ApprovalDAO(trans, cluster, AUTHZ);

+		ApprovalDAO.Data data = new ApprovalDAO.Data();

+		

+		data.ticket = UUID.randomUUID(); // normally, read from Future object

+		data.user = "testid@test.com";

+		data.approver = "mySuper@att.com";

+		data.type = "supervisor";

+		data.status = "pending";

+		data.operation = "C";

+		data.updated = new Date();

+		

+		try {

+			// Test create

+			rrDAO.create(trans, data);

+			

+			// Test Read by Ticket

+			Result<List<ApprovalDAO.Data>> rlad;

+			rlad = rrDAO.readByTicket(trans, data.ticket);

+			assertTrue(rlad.isOK());

+			assertEquals(1,rlad.value.size());

+			compare(data,rlad.value.get(0));

+			

+			// Hold onto original ID for deletion, and read tests

+			UUID id = rlad.value.get(0).id;

+			

+			try {

+				// Test Read by User

+				rlad = rrDAO.readByUser(trans, data.user);

+				assertTrue(rlad.isOKhasData());

+				boolean ok = false;

+				for(ApprovalDAO.Data a : rlad.value) {

+					if(a.id.equals(id)) {

+						ok = true;

+						compare(data,a);

+					}

+				}

+				assertTrue(ok);

+	

+				// Test Read by Approver

+				rlad = rrDAO.readByApprover(trans, data.approver);

+				assertTrue(rlad.isOKhasData());

+				ok = false;

+				for(ApprovalDAO.Data a : rlad.value) {

+					if(a.id.equals(id)) {

+						ok = true;

+						compare(data,a);

+					}

+				}

+				assertTrue(ok);

+	

+				// Test Read by ID

+				rlad = rrDAO.read(trans, id);

+				assertTrue(rlad.isOKhasData());

+				ok = false;

+				for(ApprovalDAO.Data a : rlad.value) {

+					if(a.id.equals(id)) {

+						ok = true;

+						compare(data,a);

+					}

+				}

+				assertTrue(ok);

+	

+				// Test Update

+				data.status = "approved";

+				data.id = id;

+				assertTrue(rrDAO.update(trans, data).isOK());

+				

+				rlad = rrDAO.read(trans, id);

+				assertTrue(rlad.isOKhasData());

+				ok = false;

+				for(ApprovalDAO.Data a : rlad.value) {

+					if(a.id.equals(id)) {

+						ok = true;

+						compare(data,a);

+					}

+				}

+				assertTrue(ok);

+

+			} finally {

+				// Delete

+				data.id = id;

+				rrDAO.delete(trans, data, true);

+				rlad = rrDAO.read(trans, id);

+				assertTrue(rlad.isOK());

+				assertTrue(rlad.isEmpty());

+			}

+			

+		} finally {

+			rrDAO.close(trans);

+		}

+	}

+

+	private void compare(Data d1, Data d2) {

+		assertNotSame(d1.id,d2.id);

+		assertEquals(d1.ticket,d2.ticket);

+		assertEquals(d1.user,d2.user);

+		assertEquals(d1.approver,d2.approver);

+		assertEquals(d1.type,d2.type);

+		assertEquals(d1.status,d2.status);

+		assertEquals(d1.operation,d2.operation);

+		assertNotSame(d1.updated,d2.updated);

+	}

+

+	

+	

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ArtiDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ArtiDAO.java
new file mode 100644
index 0000000..0c92dc7
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_ArtiDAO.java
@@ -0,0 +1,137 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO.Data;

+

+/**

+ * UserDAO unit test.

+ * User: tp007s

+ * Date: 7/19/13

+ */

+public class JU_ArtiDAO  extends AbsJUCass {

+	@Test

+	public void test() throws IOException, NoSuchAlgorithmException {

+		ArtiDAO adao = new ArtiDAO(trans,cluster,"authz");

+		try {

+			// Create

+	        ArtiDAO.Data data = new ArtiDAO.Data();

+	        data.mechid="m55555@perturbed.att.com";

+	        data.machine="perturbed1232.att.com";

+	        data.type(false).add("file");

+	        data.type(false).add("jks");

+	        data.sponsor="Fred Flintstone";

+	        data.ca="devl";

+	        data.dir="/opt/app/aft/keys";

+	        data.appName="kumquat";

+	        data.os_user="aft";

+	        data.notify="email:myname@bogus.email.com";

+	        data.expires=new Date();

+	        

+//	        Bytification

+	        ByteBuffer bb = data.bytify();

+	        Data bdata = new ArtiDAO.Data();

+	        bdata.reconstitute(bb);

+	        checkData1(data, bdata);

+	        

+	        

+//	        DB work

+			adao.create(trans,data);

+			try {

+				// Validate Read with key fields in Data

+				Result<List<ArtiDAO.Data>> rlcd = adao.read(trans,data);

+				assertTrue(rlcd.isOKhasData());

+				for(ArtiDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}

+	

+				// Validate Read with key fields in Data

+				rlcd = adao.read(trans,data.mechid, data.machine);

+				assertTrue(rlcd.isOKhasData());

+				for(ArtiDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}

+	

+				// By Machine

+				rlcd = adao.readByMachine(trans,data.machine);

+				assertTrue(rlcd.isOKhasData());

+				for(ArtiDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}

+				

+				// By MechID

+				rlcd = adao.readByMechID(trans,data.mechid);

+				assertTrue(rlcd.isOKhasData());

+				for(ArtiDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}

+	

+				// Update

+				data.sponsor = "Wilma Flintstone";

+				adao.update(trans,data);

+				rlcd = adao.read(trans,data);

+				assertTrue(rlcd.isOKhasData());

+				for(ArtiDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}			

+

+			} finally {

+				// Always delete data, even if failure.

+				adao.delete(trans,data, true);

+			}

+		} finally {

+			adao.close(trans);

+		}

+

+		

+	}

+

+	private void checkData1(Data data, Data d) {

+		assertEquals(data.mechid,d.mechid);

+		assertEquals(data.machine,d.machine);

+		assertEquals(data.type(false).size(),d.type(false).size());

+		for(String s: data.type(false)) {

+			assertTrue(d.type(false).contains(s));

+		}

+		assertEquals(data.sponsor,d.sponsor);

+		assertEquals(data.ca,d.ca);

+		assertEquals(data.dir,d.dir);

+		assertEquals(data.appName,d.appName);

+		assertEquals(data.os_user,d.os_user);

+		assertEquals(data.notify,d.notify);

+		assertEquals(data.expires,d.expires);

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_Bytification.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_Bytification.java
new file mode 100644
index 0000000..65efef4
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_Bytification.java
@@ -0,0 +1,266 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.Date;

+

+import org.junit.Test;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+

+public class JU_Bytification {

+

+	@Test

+	public void testNS() throws IOException {

+		

+		// Normal

+		NsDAO.Data ns = new NsDAO.Data();

+		ns.name = "com.att.<pass>";

+		ns.type = NsType.APP.type;

+

+		ByteBuffer bb = ns.bytify();

+		

+		NsDAO.Data nsr = new NsDAO.Data();

+		nsr.reconstitute(bb);

+		check(ns,nsr);

+		

+		// Empty admin

+//		ns.admin(true).clear();

+		bb = ns.bytify();

+		nsr = new NsDAO.Data();

+		nsr.reconstitute(bb);

+		check(ns,nsr);

+		

+		// Empty responsible

+//		ns.responsible(true).clear();

+		bb = ns.bytify();

+		nsr = new NsDAO.Data();

+		nsr.reconstitute(bb);

+		check(ns,nsr);

+

+		bb = ns.bytify();

+		nsr = new NsDAO.Data();

+		nsr.reconstitute(bb);

+		check(ns,nsr);

+	}

+	

+	private void check(NsDAO.Data a, NsDAO.Data b) {

+		assertEquals(a.name,b.name);

+		assertEquals(a.type,b.type);

+//		assertEquals(a.admin.size(),b.admin.size());

+		

+//		for(String s: a.admin) {

+//			assertTrue(b.admin.contains(s));

+//		}

+//		

+//		assertEquals(a.responsible.size(),b.responsible.size());

+//		for(String s: a.responsible) {

+//			assertTrue(b.responsible.contains(s));

+//		}

+	}

+

+	@Test

+	public void testRole() throws IOException {

+		RoleDAO.Data rd1 = new RoleDAO.Data();

+		rd1.ns = "com.att.<pass>";

+		rd1.name = "my.role";

+		rd1.perms(true).add("com.att.<pass>.my.Perm|myInstance|myAction");

+		rd1.perms(true).add("com.att.<pass>.my.Perm|myInstance|myAction2");

+

+		// Normal

+		ByteBuffer bb = rd1.bytify();

+		RoleDAO.Data rd2 = new RoleDAO.Data();

+		rd2.reconstitute(bb);

+		check(rd1,rd2);

+		

+		// Overshoot Buffer

+		StringBuilder sb = new StringBuilder(300);

+		sb.append("role|instance|veryLongAction...");

+		for(int i=0;i<280;++i) {

+			sb.append('a');

+		}

+		rd1.perms(true).add(sb.toString());

+		bb = rd1.bytify();

+		rd2 = new RoleDAO.Data();

+		rd2.reconstitute(bb);

+		check(rd1,rd2);

+		

+		// No Perms

+		rd1.perms.clear();

+		

+		bb = rd1.bytify();

+		rd2 = new RoleDAO.Data();

+		rd2.reconstitute(bb);

+		check(rd1,rd2);

+		

+		// 1000 Perms

+		for(int i=0;i<1000;++i) {

+			rd1.perms(true).add("com|inst|action"+ i);

+		}

+

+		bb = rd1.bytify();

+		rd2 = new RoleDAO.Data();

+		rd2.reconstitute(bb);

+		check(rd1,rd2);

+

+	}

+	

+	private void check(RoleDAO.Data a, RoleDAO.Data b) {

+		assertEquals(a.ns,b.ns);

+		assertEquals(a.name,b.name);

+		

+		assertEquals(a.perms.size(),b.perms.size());

+		for(String s: a.perms) {

+			assertTrue(b.perms.contains(s));

+		}

+	}

+

+	@Test

+	public void testPerm() throws IOException {

+		PermDAO.Data pd1 = new PermDAO.Data();

+		pd1.ns = "com.att.<pass>";

+		pd1.type = "my.perm";

+		pd1.instance = "instance";

+		pd1.action = "read";

+		pd1.roles(true).add("com.att.<pass>.my.Role");

+		pd1.roles(true).add("com.att.<pass>.my.Role2");

+

+		// Normal

+		ByteBuffer bb = pd1.bytify();

+		PermDAO.Data rd2 = new PermDAO.Data();

+		rd2.reconstitute(bb);

+		check(pd1,rd2);

+		

+		// No Perms

+		pd1.roles.clear();

+		

+		bb = pd1.bytify();

+		rd2 = new PermDAO.Data();

+		rd2.reconstitute(bb);

+		check(pd1,rd2);

+		

+		// 1000 Perms

+		for(int i=0;i<1000;++i) {

+			pd1.roles(true).add("com.att.<pass>.my.Role"+ i);

+		}

+

+		bb = pd1.bytify();

+		rd2 = new PermDAO.Data();

+		rd2.reconstitute(bb);

+		check(pd1,rd2);

+

+	}

+	

+	private void check(PermDAO.Data a, PermDAO.Data b) {

+		assertEquals(a.ns,b.ns);

+		assertEquals(a.type,b.type);

+		assertEquals(a.instance,b.instance);

+		assertEquals(a.action,b.action);

+		

+		assertEquals(a.roles.size(),b.roles.size());

+		for(String s: a.roles) {

+			assertTrue(b.roles.contains(s));

+		}

+	}

+

+	@Test

+	public void testUserRole() throws IOException {

+		UserRoleDAO.Data urd1 = new UserRoleDAO.Data();

+		urd1.user = "myname@abc.att.com";

+		urd1.role("com.att.<pass>","my.role");

+		urd1.expires = new Date();

+

+		// Normal

+		ByteBuffer bb = urd1.bytify();

+		UserRoleDAO.Data urd2 = new UserRoleDAO.Data();

+		urd2.reconstitute(bb);

+		check(urd1,urd2);

+		

+		// A null

+		urd1.expires = null; 

+		urd1.role = null;

+		

+		bb = urd1.bytify();

+		urd2 = new UserRoleDAO.Data();

+		urd2.reconstitute(bb);

+		check(urd1,urd2);

+	}

+

+	private void check(UserRoleDAO.Data a, UserRoleDAO.Data b) {

+		assertEquals(a.user,b.user);

+		assertEquals(a.role,b.role);

+		assertEquals(a.expires,b.expires);

+	}

+

+	

+	@Test

+	public void testCred() throws IOException {

+		CredDAO.Data cd = new CredDAO.Data();

+		cd.id = "m55555@abc.att.com";

+		cd.ns = "com.att.abc";

+		cd.type = 2;

+		cd.cred = ByteBuffer.wrap(new byte[]{1,34,5,3,25,0,2,5,3,4});

+		cd.expires = new Date();

+

+		// Normal

+		ByteBuffer bb = cd.bytify();

+		CredDAO.Data cd2 = new CredDAO.Data();

+		cd2.reconstitute(bb);

+		check(cd,cd2);

+		

+		// nulls

+		cd.expires = null;

+		cd.cred = null;

+		

+		bb = cd.bytify();

+		cd2 = new CredDAO.Data();

+		cd2.reconstitute(bb);

+		check(cd,cd2);

+

+	}

+

+	private void check(CredDAO.Data a, CredDAO.Data b) {

+		assertEquals(a.id,b.id);

+		assertEquals(a.ns,b.ns);

+		assertEquals(a.type,b.type);

+		if(a.cred==null) {

+			assertEquals(a.cred,b.cred); 

+		} else {

+			int l = a.cred.limit();

+			assertEquals(l,b.cred.limit());

+			for (int i=0;i<l;++i) {

+				assertEquals(a.cred.get(),b.cred.get());

+			}

+		}

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CacheInfoDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CacheInfoDAO.java
new file mode 100644
index 0000000..a2e96f2
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CacheInfoDAO.java
@@ -0,0 +1,65 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import java.io.IOException;

+import java.util.Date;

+

+import org.junit.Test;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.CIDAO;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.cass.CacheInfoDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Chrono;

+

+import junit.framework.Assert;

+

+

+public class JU_CacheInfoDAO extends AbsJUCass {

+

+	@Test

+	public void test() throws DAOException, APIException, IOException {

+		CIDAO<AuthzTrans> id = new CacheInfoDAO(trans, cluster, AUTHZ);

+		Date date  = new Date();

+		

+		id.touch(trans, RoleDAO.TABLE,1);

+		try {

+			Thread.sleep(3000);

+		} catch (InterruptedException e) {

+		}

+		Result<Void> rid = id.check(trans);

+		Assert.assertEquals(rid.status,Status.OK);

+		Date[] dates = CacheInfoDAO.info.get(RoleDAO.TABLE);

+		if(dates.length>0 && dates[1]!=null) {

+			System.out.println(Chrono.dateStamp(dates[1]));

+			System.out.println(Chrono.dateStamp(date));

+			Assert.assertTrue(Math.abs(dates[1].getTime() - date.getTime())<20000); // allow for 4 seconds, given Remote DB

+		}

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CertDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CertDAO.java
new file mode 100644
index 0000000..498f8ce
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CertDAO.java
@@ -0,0 +1,105 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.math.BigInteger;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * UserDAO unit test.

+ * User: tp007s

+ * Date: 7/19/13

+ */

+public class JU_CertDAO  extends AbsJUCass {

+	@Test

+	public void test() throws IOException, NoSuchAlgorithmException, APIException {

+		CertDAO cdao = new CertDAO(trans,cluster,"authz");

+		try {

+			// Create

+	        CertDAO.Data data = new CertDAO.Data();

+	        data.serial=new BigInteger("11839383");

+	        data.id = "m55555@tguard.att.com";

+	        data.x500="CN=ju_cert.dao.att.com, OU=AAF, O=\"ATT Services, Inc.\", L=Southfield, ST=Michigan, C=US";

+	        data.x509="I'm a cert";

+	        data.ca = "aaf";

+			cdao.create(trans,data);

+

+//	        Bytification

+	        ByteBuffer bb = data.bytify();

+	        Data bdata = new CertDAO.Data();

+	        bdata.reconstitute(bb);

+	        checkData1(data, bdata);

+

+			// Validate Read with key fields in Data

+			Result<List<CertDAO.Data>> rlcd = cdao.read(trans,data);

+			assertTrue(rlcd.isOKhasData());

+			for(CertDAO.Data d : rlcd.value) {

+				checkData1(data,d);

+			}

+

+			// Validate Read with key fields in Data

+			rlcd = cdao.read(trans,data.ca,data.serial);

+			assertTrue(rlcd.isOKhasData());

+			for(CertDAO.Data d : rlcd.value) {

+				checkData1(data,d);

+			}

+

+			// Update

+			data.id = "m66666.tguard.att.com";

+			cdao.update(trans,data);

+			rlcd = cdao.read(trans,data);

+			assertTrue(rlcd.isOKhasData());

+			for(CertDAO.Data d : rlcd.value) {

+				checkData1(data,d);

+			}			

+			

+			cdao.delete(trans,data, true);

+		} finally {

+			cdao.close(trans);

+		}

+

+		

+	}

+

+	private void checkData1(Data data, Data d) {

+		assertEquals(data.ca,d.ca);

+		assertEquals(data.serial,d.serial);

+		assertEquals(data.id,d.id);

+		assertEquals(data.x500,d.x500);

+		assertEquals(data.x509,d.x509);

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CredDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CredDAO.java
new file mode 100644
index 0000000..3cf860a
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_CredDAO.java
@@ -0,0 +1,252 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * UserDAO unit test.

+ * User: tp007s

+ * Date: 7/19/13

+ */

+public class JU_CredDAO  extends AbsJUCass {

+	@Test

+	public void test() throws IOException, NoSuchAlgorithmException, APIException {

+		CredDAO udao = new CredDAO(trans,cluster,"authz");

+		try {

+			// Create

+	        CredDAO.Data data = new CredDAO.Data();

+	        data.id = "m55555@aaf.att.com";

+	        data.type = CredDAO.BASIC_AUTH;

+	        data.notes = "temp pass";

+	        data.cred      = ByteBuffer.wrap(userPassToBytes("m55555","mypass"));

+	        data.other = 12;

+	        data.expires = new Date(System.currentTimeMillis() + 60000*60*24*90);

+			udao.create(trans,data);

+			

+//	        Bytification

+	        ByteBuffer bb = data.bytify();

+	        Data bdata = new CredDAO.Data();

+	        bdata.reconstitute(bb);

+	        checkData1(data, bdata);

+

+			// Validate Read with key fields in Data

+			Result<List<CredDAO.Data>> rlcd = udao.read(trans,data);

+			assertTrue(rlcd.isOKhasData());

+			for(CredDAO.Data d : rlcd.value) {

+				checkData1(data,d);

+			}

+			

+			// Update

+			data.cred = ByteBuffer.wrap(userPassToBytes("m55555","mynewpass"));

+			udao.update(trans,data);

+			rlcd = udao.read(trans,data);

+			assertTrue(rlcd.isOKhasData());

+			for(CredDAO.Data d : rlcd.value) {

+				checkData1(data,d);

+			}			

+			

+			udao.delete(trans,data, true);

+		} finally {

+			udao.close(trans);

+		}

+

+		

+	}

+

+	private void checkData1(Data data, Data d) {

+		assertEquals(data.id,d.id);

+		assertEquals(data.type,d.type);

+		assertEquals(data.ns,d.ns);

+		assertEquals(data.notes,d.notes);

+		assertEquals(data.cred,d.cred);

+		assertEquals(data.other,d.other);

+		assertEquals(data.expires,d.expires);

+	}

+

+//    private String                          CONST_myName = "MyName";

+//    public static final java.nio.ByteBuffer CONST_MY_CRED = get_CONST_MY_CRED();

+//    public static final int                 CONST_CRED_TYPE = 11;

+//

+//    public static final Date                CONST_UPDATE_DATE = new Date(System.currentTimeMillis()+60000*24);

+//    @Test

+//    public void test() {

+//        UserDAO ud = new UserDAO(trans, cluster,"authz");

+//        try {

+//            UserDAO.Data data = createPrototypeUserData();

+//            ud.create(trans, data);

+//

+//            // Validate Read with key fields in Data

+//            for(UserDAO.Data d : ud.read(trans, data)) {

+//                checkData1(data,d);

+//            }

+//

+//            // Validate readByName

+//            for(UserDAO.Data d : ud.read(trans, CONST_myName)) {

+//                checkData1(data,d);

+//            }

+//

+//            ud.delete(trans, data);

+//            List<UserDAO.Data> d_2 = ud.read(trans, CONST_myName);

+//

+//            // Validate that data was deleted

+//            assertEquals("User should not be found after deleted", 0, d_2.size() );

+//

+//            data = new UserDAO.Data();

+//            data.name = CONST_myName;

+//            data.cred = CONST_MY_CRED;

+//            data.cred_type= CONST_CRED_TYPE;

+//            data.expires = new Date(System.currentTimeMillis()+60000*24);

+//            final Result<UserDAO.Data> user = ud.r_create(trans, data);

+//            assertEquals("ud.createUser should work", Result.Status.OK, user.status);

+//

+//            checkDataIgnoreDateDiff(data, user.value);

+//

+//            // finally leave system in consistent state by deleting user again

+//            ud.delete(trans,data);

+//

+//        } catch (DAOException e) {

+//            e.printStackTrace();

+//            fail("Fail due to Exception");

+//        } finally {

+//            ud.close(trans);

+//        }

+//    }

+//

+//    private UserDAO.Data createPrototypeUserData() {

+//        UserDAO.Data data = new UserDAO.Data();

+//        data.name = CONST_myName;

+//

+//        data.cred_type = CONST_CRED_TYPE;

+//        data.cred      = CONST_MY_CRED;

+//        data.expires = CONST_UPDATE_DATE;

+//        return data;

+//    }

+//

+//    //    @Test

+//    //    public void testReadByUser() throws Exception {

+//    //           // this test was done above in our super test, since it uses the same setup

+//    //    }

+//

+//    @Test

+//    public void testFunctionCreateUser() throws Exception {

+//        String name = "roger_rabbit";

+//        Integer credType = CONST_CRED_TYPE;

+//        java.nio.ByteBuffer cred = CONST_MY_CRED;

+//        final UserDAO ud = new UserDAO(trans, cluster,"authz");

+//        final UserDAO.Data data = createPrototypeUserData();

+//        Result<UserDAO.Data> ret = ud.r_create(trans, data);

+//        Result<List<Data>> byUserNameLookup = ud.r_read(trans, name);

+//        

+//        assertEquals("sanity test w/ different username (different than other test cases) failed", name, byUserNameLookup.value.get(0).name);

+//        assertEquals("delete roger_rabbit failed", true, ud.delete(trans, byUserNameLookup.value.get(0)));

+//    }

+//

+//    @Test

+//    public void testLowLevelCassandraCreateData_Given_UserAlreadyPresent_ShouldPass() throws Exception {

+//        UserDAO ud = new UserDAO(trans, cluster,"authz");

+//

+//        final UserDAO.Data data = createPrototypeUserData();

+//        final UserDAO.Data data1 = ud.create(trans, data);

+//        final UserDAO.Data data2 = ud.create(trans, data);

+//

+//        assertNotNull(data1);

+//        assertNotNull(data2);

+//

+//        assertEquals(CONST_myName, data1.name);

+//        assertEquals(CONST_myName, data2.name);

+//    }

+//

+//    @Test

+//    public void testCreateUser_Given_UserAlreadyPresent_ShouldFail() throws Exception {

+//        UserDAO ud = new UserDAO(trans, cluster,"authz");

+//

+//        final UserDAO.Data data = createPrototypeUserData();

+//

+//        // make sure that some prev test did not leave the user in the DB

+//        ud.delete(trans, data);

+//

+//        // attempt to create same user twice !!!

+//        

+//        final Result<UserDAO.Data> data1 = ud.r_create(trans, data);

+//        final Result<UserDAO.Data> data2 = ud.r_create(trans, data);

+//

+//        assertNotNull(data1);

+//        assertNotNull(data2);

+//

+//        assertEquals(true,   Result.Status.OK == data1.status);

+//        assertEquals(false,  Result.Status.OK == data2.status);

+//    }

+//

+//    private void checkData1(UserDAO.Data data, UserDAO.Data d) {

+//        data.name = CONST_myName;

+//

+//        data.cred_type = CONST_CRED_TYPE;

+//        data.cred      = CONST_MY_CRED;

+//        data.expires   = CONST_UPDATE_DATE;

+//

+//        assertEquals(data.name, d.name);

+//        assertEquals(data.cred_type, d.cred_type);

+//        assertEquals(data.cred, d.cred);

+//        assertEquals(data.expires, d.expires);

+//

+//    }

+//

+//    private void checkDataIgnoreDateDiff(UserDAO.Data data, UserDAO.Data d) {

+//        data.name = CONST_myName;

+//

+//        data.cred_type = CONST_CRED_TYPE;

+//        data.cred      = CONST_MY_CRED;

+//        data.expires   = CONST_UPDATE_DATE;

+//

+//        assertEquals(data.name, d.name);

+//        assertEquals(data.cred_type, d.cred_type);

+//        assertEquals(data.cred, d.cred);

+//         // we allow dates to be different, e.g. high level calls e.g. createUser sets the date itself.

+//        //assertEquals(data.updated, d.updated);

+//

+//    }

+//

+//    /**

+//     * Get a CONST_MY_CRED ByteBuffer, which is the java type for a cass blob.

+//     * @return

+//     */

+//    private static java.nio.ByteBuffer get_CONST_MY_CRED() {

+//     return ByteBuffer.wrap("Hello".getBytes());

+//    }

+//

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_DelegateDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_DelegateDAO.java
new file mode 100644
index 0000000..d93ec39
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_DelegateDAO.java
@@ -0,0 +1,107 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.nio.ByteBuffer;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO.Data;

+

+

+public class JU_DelegateDAO  extends AbsJUCass {

+	@Test

+	public void testCRUD() throws Exception {

+		DelegateDAO dao = new DelegateDAO(trans, cluster, AUTHZ);

+		DelegateDAO.Data data = new DelegateDAO.Data();

+		data.user = "myname";

+		data.delegate = "yourname";

+		data.expires = new Date();

+		

+//        Bytification

+        ByteBuffer bb = data.bytify();

+        Data bdata = new DelegateDAO.Data();

+        bdata.reconstitute(bb);

+        compare(data, bdata);

+

+		try {

+			// Test create

+			Result<Data> ddcr = dao.create(trans,data);

+			assertTrue(ddcr.isOK());

+			

+			

+			// Read by User

+			Result<List<DelegateDAO.Data>> records = dao.read(trans,data.user);

+			assertTrue(records.isOKhasData());

+			for(DelegateDAO.Data rdata : records.value) 

+				compare(data,rdata);

+

+			// Read by Delegate

+			records = dao.readByDelegate(trans,data.delegate);

+			assertTrue(records.isOKhasData());

+			for(DelegateDAO.Data rdata : records.value) 

+				compare(data,rdata);

+			

+			// Update

+			data.delegate = "hisname";

+			data.expires = new Date();

+			assertTrue(dao.update(trans, data).isOK());

+

+			// Read by User

+			records = dao.read(trans,data.user);

+			assertTrue(records.isOKhasData());

+			for(DelegateDAO.Data rdata : records.value) 

+				compare(data,rdata);

+

+			// Read by Delegate

+			records = dao.readByDelegate(trans,data.delegate);

+			assertTrue(records.isOKhasData());

+			for(DelegateDAO.Data rdata : records.value) 

+				compare(data,rdata);

+

+			// Test delete

+			dao.delete(trans,data, true);

+			records = dao.read(trans,data.user);

+			assertTrue(records.isEmpty());

+			

+			

+		} finally {

+			dao.close(trans);

+		}

+	}

+	

+	private void compare(Data d1, Data d2) {

+		assertEquals(d1.user, d2.user);

+		assertEquals(d1.delegate, d2.delegate);

+		assertEquals(d1.expires,d2.expires);

+	}

+

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_FastCalling.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_FastCalling.java
new file mode 100644
index 0000000..9b0fa2e
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_FastCalling.java
@@ -0,0 +1,91 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.util.Date;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class JU_FastCalling extends AbsJUCass {

+

+	@Test

+	public void test() throws IOException, NoSuchAlgorithmException, APIException {

+		trans.setProperty("cassandra.writeConsistency.cred","ONE");

+		

+		CredDAO udao = new CredDAO(env.newTransNoAvg(),cluster,"authz");

+		System.out.println("Starting calls");

+		for(iterations=0;iterations<8;++iterations) {

+			try {

+				// Create

+		        CredDAO.Data data = new CredDAO.Data();

+		        data.id = "m55555@aaf.att.com";

+		        data.type = CredDAO.BASIC_AUTH;

+		        data.cred      = ByteBuffer.wrap(userPassToBytes("m55555","mypass"));

+		        data.expires = new Date(System.currentTimeMillis() + 60000*60*24*90);

+				udao.create(trans,data);

+				

+				// Validate Read with key fields in Data

+				Result<List<CredDAO.Data>> rlcd = udao.read(trans,data);

+				assertTrue(rlcd.isOKhasData());

+				for(CredDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}

+				

+				// Update

+				data.cred = ByteBuffer.wrap(userPassToBytes("m55555","mynewpass"));

+				udao.update(trans,data);

+				rlcd = udao.read(trans,data);

+				assertTrue(rlcd.isOKhasData());

+				for(CredDAO.Data d : rlcd.value) {

+					checkData1(data,d);

+				}			

+				

+				udao.delete(trans,data, true);

+			} finally {

+				updateTotals();

+				newTrans();

+			}

+		}

+

+	}

+

+	private void checkData1(Data data, Data d) {

+		assertEquals(data.id,d.id);

+		assertEquals(data.type,d.type);

+		assertEquals(data.cred,d.cred);

+		assertEquals(data.expires,d.expires);

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_HistoryDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_HistoryDAO.java
new file mode 100644
index 0000000..29ce5d4
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_HistoryDAO.java
@@ -0,0 +1,154 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertTrue;

+

+import java.nio.ByteBuffer;

+import java.util.List;

+import java.util.Random;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+

+public class JU_HistoryDAO  extends AbsJUCass {

+	

+	@Test

+	public void testCreate() throws Exception {

+		HistoryDAO historyDAO = new HistoryDAO(trans, cluster, AUTHZ);

+		HistoryDAO.Data data = createHistoryData();

+		

+		try {

+			historyDAO.create(trans,data);			

+			Thread.sleep(200);// History Create is Async

+			Result<List<HistoryDAO.Data>> records = historyDAO.readByUser(trans,data.user,data.yr_mon);

+			assertTrue(records.isOKhasData());

+			for(HistoryDAO.Data d : records.value) {

+				assertHistory(data, d);

+			}

+		} finally {

+			historyDAO.close(trans);

+		}

+	}

+	

+	@Test

+	public void tesReadByUser() throws Exception {

+		HistoryDAO historyDAO = new HistoryDAO(trans,cluster, AUTHZ);

+		HistoryDAO.Data data = createHistoryData();

+		

+		try {

+			historyDAO.create(trans,data);

+			Thread.sleep(200);// History Create is Async

+			Result<List<HistoryDAO.Data>> records = historyDAO.readByUser(trans, data.user,data.yr_mon);

+			assertTrue(records.isOKhasData());

+			for(HistoryDAO.Data d : records.value) {

+				assertHistory(data, d);

+			}

+		} finally {

+			historyDAO.close(trans);

+		}

+	}

+	

+/*

+	@Test

+	public void readByUserAndMonth() throws Exception {

+		HistoryDAO historyDAO = new HistoryDAO(trans,cluster, AUTHZ);

+		HistoryDAO.Data data = createHistoryData();

+		

+		try {

+			historyDAO.create(trans,data);			

+			Thread.sleep(200);// History Create is Async

+			Result<List<HistoryDAO.Data>> records = historyDAO.readByUserAndMonth(trans,

+					data.user, Integer.valueOf(String.valueOf(data.yr_mon).substring(0, 4)),

+					Integer.valueOf(String.valueOf(data.yr_mon).substring(4, 6)));

+			assertTrue(records.isOKhasData());

+			for(HistoryDAO.Data d : records.value) {

+				assertHistory(data, d);

+			}

+		} finally {

+			historyDAO.close(trans);

+		}

+	}

+*/	

+	//TODO readadd this

+//	@Test

+//	public void readByUserAndDay() throws Exception {

+//		HistoryDAO historyDAO = new HistoryDAO(trans, cluster, AUTHZ);

+//		HistoryDAO.Data data = createHistoryData();

+//		

+//		try {

+//			historyDAO.create(trans, data);		

+//			Thread.sleep(200);// History Create is Async

+//			

+//			String dayTime = String.valueOf(data.day_time);

+//			String day = null;

+//			if (dayTime.length() < 8)

+//				day = dayTime.substring(0, 1);

+//			else 

+//				day = dayTime.substring(0, 2);

+//			

+//			List<HistoryDAO.Data> records = historyDAO.readByUserBetweenDates(trans,

+//							data.user, Integer.valueOf(String.valueOf(data.yr_mon).substring(0, 4)),

+//							Integer.valueOf(String.valueOf(data.yr_mon).substring(4, 6)),

+//							Integer.valueOf(day), 0);

+//			assertEquals(1,records.size());

+//			for(HistoryDAO.Data d : records) {

+//				assertHistory(data, d);

+//			}

+//		} finally {

+//			historyDAO.close(trans);

+//		}

+//	}

+	private HistoryDAO.Data createHistoryData() {

+		HistoryDAO.Data data = HistoryDAO.newInitedData();

+		Random random = new Random();

+		data.user = "test" + random.nextInt();

+		data.action = "add";

+		data.target = "history";

+		data.memo = "adding a row into history table";

+//		data.detail().put("id", "test");

+//		data.detail().put("name", "test");

+		//String temp = "Test Blob Message";

+		data.reconstruct = ByteBuffer.wrap("Temp Blob Message".getBytes());		

+		return data;

+	}

+	

+	private void assertHistory(HistoryDAO.Data ip, HistoryDAO.Data op) {

+		assertEquals(ip.yr_mon, op.yr_mon);		

+//		assertEquals(ip.day_time, op.day_time);		

+		assertEquals(ip.user, op.user);		

+		assertEquals(ip.action, op.action);

+		assertEquals(ip.target, op.target);

+		assertEquals(ip.memo, op.memo);

+		//TODO : have to see if third party assert utility can be used

+//		assertTrue(CollectionUtils.isEqualCollection(ip.detail, op.detail));

+//		for (String key : ip.detail().keySet()) {

+//			assertNotNull(op.detail().get(key));

+//		}

+		assertNotNull(op.reconstruct);

+	}

+	

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsDAO.java
new file mode 100644
index 0000000..ad9ed28
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsDAO.java
@@ -0,0 +1,187 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.Set;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+

+public class JU_NsDAO extends AbsJUCass {

+	private static final String CRM = "ju_crm";

+	private static final String SWM = "ju_swm";

+

+	@Test

+	public void test() throws APIException, IOException  {

+		NsDAO nsd = new NsDAO(trans, cluster, AUTHZ);

+		try {

+			final String nsparent = "com.test";

+			final String ns1 = nsparent +".ju_ns";

+			final String ns2 = nsparent + ".ju_ns2";

+			

+			Map<String,String> oAttribs = new HashMap<String,String>();

+			oAttribs.put(SWM, "swm_data");

+			oAttribs.put(CRM, "crm_data");

+			Data data = new NsDAO.Data();

+			data.name = ns1;

+			data.type = NsType.APP.type;

+			data.attrib(true).putAll(oAttribs);

+			

+

+			Result<List<Data>> rdrr;

+

+			// CREATE

+			Result<Data> rdc = nsd.create(trans, data);

+			assertTrue(rdc.isOK());

+			

+			try {

+//		        Bytification

+		        ByteBuffer bb = data.bytify();

+		        Data bdata = new NsDAO.Data();

+		        bdata.reconstitute(bb);

+		        compare(data, bdata);

+

+				// Test READ by Object

+				rdrr = nsd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				Data d = rdrr.value.get(0);

+				assertEquals(d.name,data.name);

+				assertEquals(d.type,data.type);

+				attribsEqual(d.attrib(false),data.attrib(false));

+				attribsEqual(oAttribs,data.attrib(false));

+				

+				// Test Read by Key

+				rdrr = nsd.read(trans, data.name);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				d = rdrr.value.get(0);

+				assertEquals(d.name,data.name);

+				assertEquals(d.type,data.type);

+				attribsEqual(d.attrib(false),data.attrib(false));

+				attribsEqual(oAttribs,data.attrib(false));

+				

+				// Read NS by Type

+				Result<Set<String>> rtypes = nsd.readNsByAttrib(trans, SWM);

+				Set<String> types;

+				if(rtypes.notOK()) {

+					throw new IOException(rtypes.errorString());

+				} else {

+					types = rtypes.value;

+				}

+				assertEquals(1,types.size());

+				assertEquals(true,types.contains(ns1));

+				

+				// Add second NS to test list of data returned

+				Data data2 = new NsDAO.Data();

+				data2.name = ns2;

+				data2.type = 3; // app

+				Result<Data> rdc2 = nsd.create(trans, data2);

+				assertTrue(rdc2.isOK());

+				

+					// Interrupt - test PARENT

+					Result<List<Data>> rdchildren = nsd.getChildren(trans, "com.test");

+					assertTrue(rdchildren.isOKhasData());

+					boolean child1 = false;

+					boolean child2 = false;

+					for(Data dchild : rdchildren.value) {

+						if(ns1.equals(dchild.name))child1=true;

+						if(ns2.equals(dchild.name))child2=true;

+					}

+					assertTrue(child1);

+					assertTrue(child2);

+

+				// FINISH DATA 2 by deleting

+				Result<Void> rddr = nsd.delete(trans, data2, true);

+				assertTrue(rddr.isOK());

+

+				// ADD DESCRIPTION

+				String description = "This is my test Namespace";

+				assertFalse(description.equalsIgnoreCase(data.description));

+				

+				Result<Void> addDesc = nsd.addDescription(trans, data.name, description);

+				assertTrue(addDesc.isOK());

+				rdrr = nsd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				assertEquals(rdrr.value.get(0).description,description);

+				

+				// UPDATE

+				String newDescription = "zz1234 Owns This Namespace Now";

+				oAttribs.put("mso", "mso_data");

+				data.attrib(true).put("mso", "mso_data");

+				data.description = newDescription;

+				Result<Void> update = nsd.update(trans, data);

+				assertTrue(update.isOK());

+				rdrr = nsd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				assertEquals(rdrr.value.get(0).description,newDescription);

+				attribsEqual(oAttribs, rdrr.value.get(0).attrib);

+				

+				

+			} catch (IOException e) {

+				e.printStackTrace();

+			} finally {

+				// DELETE

+				Result<Void> rddr = nsd.delete(trans, data, true);

+				assertTrue(rddr.isOK());

+				rdrr = nsd.read(trans, data);

+				assertTrue(rdrr.isOK() && rdrr.isEmpty());

+				assertEquals(rdrr.value.size(),0);

+			}

+		} finally {

+			nsd.close(trans);

+		}

+	}

+

+	private void compare(NsDAO.Data d, NsDAO.Data data) {

+		assertEquals(d.name,data.name);

+		assertEquals(d.type,data.type);

+		attribsEqual(d.attrib(false),data.attrib(false));

+		attribsEqual(d.attrib(false),data.attrib(false));

+	}

+	

+	private void attribsEqual(Map<String,String> aa, Map<String,String> ba) {

+		assertEquals(aa.size(),ba.size());

+		for(Entry<String, String> es : aa.entrySet()) {

+			assertEquals(es.getValue(),ba.get(es.getKey()));

+		}

+	}

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsType.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsType.java
new file mode 100644
index 0000000..9215269
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_NsType.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.AfterClass;

+import org.junit.Test;

+import org.onap.aaf.dao.aaf.cass.NsType;

+

+public class JU_NsType {

+

+	@AfterClass

+	public static void tearDownAfterClass() throws Exception {

+	}

+

+	@Test

+	public void test() {

+		NsType nt,nt2;

+		String[] tests = new String[] {"DOT","ROOT","COMPANY","APP","STACKED_APP","STACK"};

+		for(String s : tests) {

+			nt = NsType.valueOf(s);

+			assertEquals(s,nt.name());

+			

+			nt2 = NsType.fromString(s);

+			assertEquals(nt,nt2);

+			

+			int t = nt.type;

+			nt2 = NsType.fromType(t);

+			assertEquals(nt,nt2);

+		}

+		

+		nt  = NsType.fromType(Integer.MIN_VALUE);

+		assertEquals(nt,NsType.UNKNOWN);

+		nt = NsType.fromString("Garbage");

+		assertEquals(nt,NsType.UNKNOWN);

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_PermDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_PermDAO.java
new file mode 100644
index 0000000..582ce18
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_PermDAO.java
@@ -0,0 +1,176 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static junit.framework.Assert.assertEquals;

+import static junit.framework.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.List;

+import java.util.Set;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.PermDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * Test the PermissionDAO

+ * 

+ * Utilize AbsJUCass to initialize and pre-load Cass

+ * 

+ *

+ */

+public class JU_PermDAO extends AbsJUCass{

+

+	@Test

+	public void test() throws APIException, IOException {

+		PermDAO pd = new PermDAO(trans,cluster,"authz");

+		try {

+			PermDAO.Data data = new PermDAO.Data();

+			data.ns = "com.test.ju_perm";

+			data.type = "MyType";

+			data.instance = "MyInstance";

+			data.action = "MyAction";

+			data.roles(true).add(data.ns + ".dev");

+			

+

+

+			// CREATE

+			Result<Data> rpdc = pd.create(trans,data);

+			assertTrue(rpdc.isOK());

+

+			Result<List<PermDAO.Data>> rlpd;

+			try {

+//		        Bytification

+		        ByteBuffer bb = data.bytify();

+		        Data bdata = new PermDAO.Data();

+		        bdata.reconstitute(bb);

+		        compare(data, bdata);

+

+				// Validate Read with key fields in Data

+				if((rlpd = pd.read(trans,data)).isOK())

+				  for(PermDAO.Data d : rlpd.value) {

+					checkData1(data,d);

+				}

+				

+				// Validate readByName

+				if((rlpd = pd.readByType(trans,data.ns, data.type)).isOK())

+				  for(PermDAO.Data d : rlpd.value) {

+					checkData1(data,d);

+				}

+				

+				// Add Role

+				RoleDAO.Data role = new RoleDAO.Data();

+				role.ns = data.ns;

+				role.name = "test";

+				

+				Result<Void> rvpd = pd.addRole(trans, data, role.fullName());

+				assertTrue(rvpd.isOK());

+				// Validate Read with key fields in Data

+				if((rlpd = pd.read(trans,data)).isOK())

+				  for(PermDAO.Data d : rlpd.value) {

+					checkData2(data,d);

+				  }

+				

+				// Remove Role

+				rvpd = pd.delRole(trans, data, role.fullName());

+				assertTrue(rvpd.isOK());

+				if((rlpd = pd.read(trans,data)).isOK())

+					for(PermDAO.Data d : rlpd.value) {

+						checkData1(data,d);

+					}

+				

+				// Add Child

+				Data data2 = new Data();

+				data2.ns = data.ns;

+				data2.type = data.type + ".2";

+				data2.instance = data.instance;

+				data2.action = data.action;

+				

+				rpdc = pd.create(trans, data2);

+				assertTrue(rpdc.isOK());

+				try {

+					rlpd = pd.readChildren(trans, data.ns,data.type);

+					assertTrue(rlpd.isOKhasData());

+					assertEquals(rlpd.value.size(),1);

+					assertEquals(rlpd.value.get(0).fullType(),data2.fullType());

+				} finally {

+					// Delete Child

+					pd.delete(trans, data2,true);

+

+				}

+			} catch (IOException e) {

+				e.printStackTrace();

+			} finally {

+				// DELETE

+				Result<Void> rpdd = pd.delete(trans,data,true);

+				assertTrue(rpdd.isOK());

+				rlpd = pd.read(trans, data);

+				assertTrue(rlpd.isOK() && rlpd.isEmpty());

+				assertEquals(rlpd.value.size(),0);

+			}

+		} finally {

+			pd.close(trans);

+		}

+	}

+

+	private void compare(Data a, Data b) {

+		assertEquals(a.ns,b.ns);

+		assertEquals(a.type,b.type);

+		assertEquals(a.instance,b.instance);

+		assertEquals(a.action,b.action);

+		assertEquals(a.roles(false).size(),b.roles(false).size());

+		for(String s: a.roles(false)) {

+			assertTrue(b.roles(false).contains(s));

+		}

+	}

+	private void checkData1(Data data, Data d) {

+		assertEquals(data.ns,d.ns);

+		assertEquals(data.type,d.type);

+		assertEquals(data.instance,d.instance);

+		assertEquals(data.action,d.action);

+		

+		Set<String> ss = d.roles(true);

+		assertEquals(1,ss.size());

+		assertTrue(ss.contains(data.ns+".dev"));

+	}

+	

+	private void checkData2(Data data, Data d) {

+		assertEquals(data.ns,d.ns);

+		assertEquals(data.type,d.type);

+		assertEquals(data.instance,d.instance);

+		assertEquals(data.action,d.action);

+		

+		Set<String> ss = d.roles(true);

+		assertEquals(2,ss.size());

+		assertTrue(ss.contains(data.ns+".dev"));

+		assertTrue(ss.contains(data.ns+".test"));

+	}

+

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_RoleDAO.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_RoleDAO.java
new file mode 100644
index 0000000..ba61c61
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/JU_RoleDAO.java
@@ -0,0 +1,139 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import static junit.framework.Assert.assertEquals;

+import static junit.framework.Assert.assertTrue;

+

+import java.io.IOException;

+import java.nio.ByteBuffer;

+import java.util.List;

+

+import org.junit.Test;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO.Data;

+

+import org.onap.aaf.inno.env.APIException;

+

+

+public class JU_RoleDAO extends AbsJUCass {

+

+	@Test

+	public void test()  throws IOException, APIException {

+		RoleDAO rd = new RoleDAO(trans, cluster, AUTHZ);

+		try {

+			Data data = new RoleDAO.Data();

+			data.ns = "com.test.ju_role";

+			data.name = "role1";

+

+//	        Bytification

+	        ByteBuffer bb = data.bytify();

+	        Data bdata = new RoleDAO.Data();

+	        bdata.reconstitute(bb);

+	        compare(data, bdata);

+

+			// CREATE

+			Result<Data> rdc = rd.create(trans, data);

+			assertTrue(rdc.isOK());

+			Result<List<Data>> rdrr;

+			try {

+				// READ

+				rdrr = rd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				Data d = rdrr.value.get(0);

+				assertEquals(d.perms.size(),0);

+				assertEquals(d.name,data.name);

+				assertEquals(d.ns,data.ns);

+

+				PermDAO.Data perm = new PermDAO.Data();

+				perm.ns = data.ns;

+				perm.type = "Perm";

+				perm.instance = "perm1";

+				perm.action = "write";

+				

+				// ADD Perm

+				Result<Void> rdar = rd.addPerm(trans, data, perm);

+				assertTrue(rdar.isOK());

+				rdrr = rd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				assertEquals(rdrr.value.get(0).perms.size(),1);

+				assertTrue(rdrr.value.get(0).perms.contains(perm.encode()));

+				

+				// DEL Perm

+				rdar = rd.delPerm(trans, data,perm);

+				assertTrue(rdar.isOK());

+				rdrr = rd.read(trans, data);

+				assertTrue(rdrr.isOKhasData());

+				assertEquals(rdrr.value.size(),1);

+				assertEquals(rdrr.value.get(0).perms.size(),0);

+

+				// Add Child

+				Data data2 = new Data();

+				data2.ns = data.ns;

+				data2.name = data.name + ".2";

+				

+				rdc = rd.create(trans, data2);

+				assertTrue(rdc.isOK());

+				try {

+					rdrr = rd.readChildren(trans, data.ns,data.name);

+					assertTrue(rdrr.isOKhasData());

+					assertEquals(rdrr.value.size(),1);

+					assertEquals(rdrr.value.get(0).name,data.name + ".2");

+					

+					rdrr = rd.readChildren(trans, data.ns,"*");

+					assertTrue(rdrr.isOKhasData());

+					assertEquals(rdrr.value.size(),2);

+

+				} finally {

+					// Delete Child

+					rd.delete(trans, data2, true);

+				}

+	

+			} finally {

+				// DELETE

+				Result<Void> rddr = rd.delete(trans, data, true);

+				assertTrue(rddr.isOK());

+				rdrr = rd.read(trans, data);

+				assertTrue(rdrr.isOK() && rdrr.isEmpty());

+				assertEquals(rdrr.value.size(),0);

+			}

+		} finally {

+			rd.close(trans);

+		}

+	}

+

+	private void compare(Data a, Data b) {

+		assertEquals(a.name,b.name);

+		assertEquals(a.description, b.description);

+		assertEquals(a.ns,b.ns);

+		assertEquals(a.perms(false).size(),b.perms(false).size());

+		for(String p : a.perms(false)) {

+			assertTrue(b.perms(false).contains(p));

+		}

+	}

+

+}

diff --git a/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/NS_ChildUpdate.java b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/NS_ChildUpdate.java
new file mode 100644
index 0000000..379eb5e
--- /dev/null
+++ b/authz-cass/src/test/java/org/onap/aaf/dao/aaf/test/NS_ChildUpdate.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.dao.aaf.test;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+

+import com.datastax.driver.core.Cluster;

+import com.datastax.driver.core.ResultSet;

+import com.datastax.driver.core.Row;

+import com.datastax.driver.core.Session;

+

+public class NS_ChildUpdate {

+

+	public static void main(String[] args) {

+		if(args.length < 3 ) {

+			System.out.println("usage: NS_ChildUpdate machine mechid (encrypted)passwd");

+		} else {

+			try {

+				AuthzEnv env = new AuthzEnv();

+				env.setLog4JNames("log.properties","authz","authz","audit","init","trace");

+				

+				Cluster cluster = Cluster.builder()

+						.addContactPoint(args[0])

+						.withCredentials(args[1],env.decrypt(args[2], false))

+						.build();

+	

+				Session session = cluster.connect("authz");

+				try {

+					ResultSet result = session.execute("SELECT name,parent FROM ns");

+					int count = 0;

+					for(Row r : result.all()) {

+						++count;

+						String name = r.getString(0);

+						String parent = r.getString(1);

+						if(parent==null) {

+							int idx = name.lastIndexOf('.');

+							

+							parent = idx>0?name.substring(0, idx):".";

+							System.out.println("UPDATE " + name + " to " + parent);

+							session.execute("UPDATE ns SET parent='" + parent + "' WHERE name='" + name + "';");

+						}

+					}

+					System.out.println("Processed " + count + " records");

+				} finally {

+					session.close();

+					cluster.close();

+				}

+			} catch (Exception e) {

+				e.printStackTrace();

+			}

+		}

+	}

+

+}

diff --git a/authz-cass/src/test/resources/cadi.properties b/authz-cass/src/test/resources/cadi.properties
new file mode 100644
index 0000000..8f1209a
--- /dev/null
+++ b/authz-cass/src/test/resources/cadi.properties
@@ -0,0 +1,52 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.

+###############################################################################

+##

+## AUTHZ API (authz-service) Properties

+##

+

+cadi_prop_file=com.att.aaf.props;com.att.aaf.common.props

+

+#cadi_trust_all_x509=true

+#cadi_alias=aaf.att

+https.protocols=TLSv1.1,TLSv1.2

+

+cm_url=https://XXX:8150

+

+basic_realm=localized

+basic_warn=false

+localhost_deny=false

+

+cass_group_name=com.att.aaf

+cass_cluster_name=mithrilcsp.sbc.com

+aaf_default_realm=com.att.csp

+

+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE

+aaf_id=???

+aaf_password=enc:XXX

+

+aaf_user_expires=3000

+aaf_clean_interval=4000

+

diff --git a/authz-certman/pom.xml b/authz-certman/pom.xml
new file mode 100644
index 0000000..3579e1b
--- /dev/null
+++ b/authz-certman/pom.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-certman</artifactId>

+	<name>AAF Certification Managmenent</name>

+	<description>Certificate Manager API</description>

+		<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>

+		<project.swmVersion>45</project.swmVersion>

+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

+		<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+	</properties>

+		

+	<dependencies>

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-core</artifactId>

+        </dependency>

+

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-cass</artifactId>

+        </dependency>

+

+	    

+		<dependency> 

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+		</dependency>

+		

+		<dependency>

+			<groupId>com.google.code.jscep</groupId>

+			<artifactId>jscep</artifactId>

+			<version>2.4.0</version>

+		</dependency>

+		<!--  TESTING -->

+		<dependency>

+			<groupId>org.slf4j</groupId>

+			<artifactId>slf4j-log4j12</artifactId>

+		</dependency>

+	</dependencies>

+	

+	<build>

+		<plugins>

+            <plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-jar-plugin</artifactId>

+					<configuration>

+	                	<includes>

+	                		<include>**/*.class</include>

+	                	</includes>

+					</configuration>

+					<version>2.3.1</version>

+				</plugin>

+			    

+				<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->

+			

+			    <plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<configuration>

+						<skip>true</skip>

+					</configuration>

+			    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin>

+

+			</plugins>

+		<pluginManagement>

+			<plugins/>

+		</pluginManagement>

+	</build>

+<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>	

+</project>

diff --git a/authz-certman/src/main/config/certman.props b/authz-certman/src/main/config/certman.props
new file mode 100644
index 0000000..496d8c3
--- /dev/null
+++ b/authz-certman/src/main/config/certman.props
@@ -0,0 +1,25 @@
+##
+## AUTHZ Certman (authz-certman) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+##DME2 related parameters
+DMEServiceName=service=com.att.authz.certman/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_CERTMAN_PORT_RANGE_
+
+# Turn on both AAF TAF & LUR 2.0                                                
+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+
+
+
diff --git a/authz-certman/src/main/config/log4j.properties b/authz-certman/src/main/config/log4j.properties
new file mode 100644
index 0000000..ed7f1ca
--- /dev/null
+++ b/authz-certman/src/main/config/log4j.properties
@@ -0,0 +1,78 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}

+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.INIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+

+log4j.appender.CM=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.CM.File=_LOG_DIR_/${LOG4J_FILENAME_cm}

+log4j.appender.CM.DatePattern='.'yyyy-MM-dd

+#log4j.appender.CM.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.CM.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.CM.layout=org.apache.log4j.PatternLayout 

+log4j.appender.CM.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %p [%c] %m %n

+

+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}

+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.AUDIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.AUDIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.AUDIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+

+# General Apache libraries

+log4j.rootLogger=INFO,CM

+log4j.logger.org.apache=WARN,INIT

+log4j.logger.dme2=WARN,INIT

+log4j.logger.init=INFO,INIT

+log4j.logger.authz=_LOG4J_LEVEL_,CM

+log4j.logger.audit=INFO,AUDIT

+log4j.category.org.jscep=INFO

+

diff --git a/authz-certman/src/main/config/lrm-authz-certman.xml b/authz-certman/src/main/config/lrm-authz-certman.xml
new file mode 100644
index 0000000..9fd99a3
--- /dev/null
+++ b/authz-certman/src/main/config/lrm-authz-certman.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">

+    <ns2:ManagedResource>

+        <ResourceDescriptor>

+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>

+            <ResourceVersion>

+                <Major>_MAJOR_VER_</Major>

+                <Minor>_MINOR_VER_</Minor>

+                <Patch>_PATCH_VER_</Patch>                

+            </ResourceVersion>

+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>

+        </ResourceDescriptor>

+        <ResourceType>Java</ResourceType>

+        <ResourcePath>com.att.authz.cm.service.CertManAPI</ResourcePath>

+        <ResourceProps>

+            <Tag>process.workdir</Tag>

+            <Value>_ROOT_DIR_</Value>

+        </ResourceProps>    	       

+        <ResourceProps>

+            <Tag>jvm.version</Tag>

+            <Value>1.8</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.args</Tag>

+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.classpath</Tag>

+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.min</Tag>

+            <Value>1024m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.max</Tag>

+            <Value>2048m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>start.class</Tag>

+            <Value>com.att.authz.cm.service.CertManAPI</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stdout.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stderr.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>

+        </ResourceProps>

+        <ResourceOSID>aft</ResourceOSID>

+        <ResourceStartType>AUTO</ResourceStartType>

+        <ResourceStartPriority>2</ResourceStartPriority>

+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>

+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        

+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>

+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>

+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>

+    </ns2:ManagedResource>

+</ns2:ManagedResourceList>

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Artifact.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Artifact.java
new file mode 100644
index 0000000..29362df
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Artifact.java
@@ -0,0 +1,130 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.api;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.cm.mapper.Mapper.API;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.cm.service.Code;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+/**

+ * API Deployment Artifact Apis.. using Redirect for mechanism

+ * 

+ *

+ */

+public class API_Artifact {

+	private static final String GET_ARTIFACTS = "Get Artifacts";

+

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param cmAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final CertManAPI cmAPI) throws Exception {

+		cmAPI.route(HttpMethods.POST, "/cert/artifacts", API.ARTIFACTS, new Code(cmAPI,"Create Artifacts") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.createArtifacts(trans, req, resp);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.CREATED_201);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		cmAPI.route(HttpMethods.GET, "/cert/artifacts/:mechid/:machine", API.ARTIFACTS, new Code(cmAPI,GET_ARTIFACTS) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.readArtifacts(trans, resp, pathParam(req,":mechid"), pathParam(req,":machine"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.CREATED_201);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		cmAPI.route(HttpMethods.GET, "/cert/artifacts", API.ARTIFACTS, new Code(cmAPI,GET_ARTIFACTS) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.readArtifacts(trans, req, resp);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.CREATED_201);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		cmAPI.route(HttpMethods.PUT, "/cert/artifacts", API.ARTIFACTS, new Code(cmAPI,"Update Artifacts") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.updateArtifacts(trans, req, resp);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		cmAPI.route(HttpMethods.DELETE, "/cert/artifacts/:mechid/:machine", API.VOID, new Code(cmAPI,"Delete Artifacts") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteArtifacts(trans, resp, 

+						pathParam(req, ":mechid"), pathParam(req,":machine"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+		

+

+		cmAPI.route(HttpMethods.DELETE, "/cert/artifacts", API.VOID, new Code(cmAPI,"Delete Artifacts") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteArtifacts(trans, req, resp);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+		

+

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Cert.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Cert.java
new file mode 100644
index 0000000..d8cdf26
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/api/API_Cert.java
@@ -0,0 +1,100 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.api;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.mapper.Mapper.API;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.cm.service.Code;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TransStore;

+

+/**

+ * API Apis.. using Redirect for mechanism

+ * 

+ *

+ */

+public class API_Cert {

+	public static final String CERT_AUTH = "CertAuthority";

+	private static Slot sCertAuth;

+

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param cmAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final CertManAPI cmAPI) throws Exception {

+		// Check for Created Certificate Authorities in TRANS

+		sCertAuth = ((TransStore) cmAPI.env).slot(CERT_AUTH);

+		

+		////////

+		// Overall APIs

+		///////

+		cmAPI.route(HttpMethods.PUT,"/cert/:ca",API.CERT_REQ,new Code(cmAPI,"Request Certificate") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String key = pathParam(req, ":ca");

+				CA ca;

+				if((ca = cmAPI.getCA(key))==null) {

+					context.error(trans,resp,Result.ERR_BadData,"CA %s is not supported",key);

+				} else {

+					trans.put(sCertAuth, ca);

+					

+					Result<Void> r = context.requestCert(trans, req, resp, req.getParameter("withTrust")!=null);

+					if(r.isOK()) {

+						resp.setStatus(HttpStatus.OK_200);

+					} else {

+						context.error(trans,resp,r);

+					}

+				}

+			}

+		});

+		

+		/**

+		 * 

+		 */

+		cmAPI.route(HttpMethods.GET, "/cert/may/:perm", API.VOID, new Code(cmAPI,"Check Permission") {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.check(trans, resp, pathParam(req,"perm"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					trans.checkpoint(r.errorString());

+					context.error(trans,resp,Result.err(Result.ERR_Denied,"%s does not have Permission.",trans.user()));

+				}

+			}

+		});

+

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/AppCA.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/AppCA.java
new file mode 100644
index 0000000..79e7fff
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/AppCA.java
@@ -0,0 +1,356 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.ca;

+

+import java.io.File;

+import java.io.IOException;

+import java.net.Authenticator;

+import java.net.MalformedURLException;

+import java.net.PasswordAuthentication;

+import java.net.URL;

+import java.security.cert.CertStore;

+import java.security.cert.CertStoreException;

+import java.security.cert.Certificate;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Date;

+import java.util.Iterator;

+import java.util.List;

+

+import org.bouncycastle.operator.OperatorCreationException;

+import org.bouncycastle.pkcs.PKCS10CertificationRequest;

+import org.jscep.client.Client;

+import org.jscep.client.ClientException;

+import org.jscep.client.EnrollmentResponse;

+import org.jscep.client.verification.CertificateVerifier;

+import org.jscep.transaction.TransactionException;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.authz.cm.cert.StandardFields;

+import org.onap.aaf.authz.common.Define;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.cadi.routing.GreatCircle;

+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.Split;

+

+public class AppCA extends CA {

+	public static final String CA_PERM_TYPE = Define.ROOT_NS+".ca"; // Permission Type for validation

+	private static final String AAF_DATA_DIR = "aaf_data_dir";

+	private static final String CA_PREFIX = "http://";

+	private static final String CA_POSTFIX="/certsrv/mscep_admin/mscep.dll";

+

+	private final static String MS_PROFILE="1";

+	private static final String CM_TRUST_CAS = "cm_trust_cas";

+	private Clients clients;

+

+	private static class AAFStdFields implements StandardFields {

+		private final String env;

+		public AAFStdFields(Trans trans) throws CertException {

+	 		env = trans.getProperty(Config.AAF_ENV);

+			if(env==null) {

+				throw new CertException(Config.AAF_ENV + " must be set to create Certificates");

+			}

+		}

+		@Override

+		public void set(CSRMeta csr) {

+			// Environment

+			csr.environment(env);

+			// Standard Fields

+			csr.o("ATT Services,Inc.");

+			csr.l("St Louis");

+			csr.st("Missouri");

+			csr.c("US");

+		}

+	}

+

+	public AppCA(final Trans trans, final String name, final String urlstr, final String id, final String pw) throws IOException, CertificateException, CertException {

+ 		super(name,new AAFStdFields(trans), CA_PERM_TYPE);

+		

+		clients = new Clients(trans,urlstr);

+		

+ 		

+		// Set this for NTLM password Microsoft

+		Authenticator.setDefault(new Authenticator() {

+			  public PasswordAuthentication getPasswordAuthentication () {

+		            return new PasswordAuthentication (

+		            		id,

+		             		trans.decryptor().decrypt(pw).toCharArray());

+		        }

+		});

+

+

+

+		try {

+			StringBuilder sb = new StringBuilder("CA Reported Trusted Certificates");

+			List<X509Certificate> trustCerts = new ArrayList<X509Certificate>();

+			for(Client client : clients) {

+				CertStore cs = client.getCaCertificate(MS_PROFILE);

+				

+				Collection<? extends Certificate> cc = cs.getCertificates(null);

+				for(Certificate c : cc) {

+					X509Certificate xc = (X509Certificate)c;

+					// Avoid duplicate Certificates from multiple servers

+					X509Certificate match = null;

+					for(X509Certificate t : trustCerts) {

+						if(t.getSerialNumber().equals(xc.getSerialNumber())) {

+							match = xc;

+							break;

+						}

+					}

+					if(match==null && xc.getSubjectDN().getName().startsWith("CN=ATT ")) {

+						sb.append("\n\t");

+						sb.append(xc.getSubjectDN());

+						sb.append("\n\t\tSerial Number: ");

+						String bi = xc.getSerialNumber().toString(16);

+						for(int i=0;i<bi.length();++i) {

+							if(i>1 && i%2==0) {

+								sb.append(':');

+							}

+							sb.append(bi.charAt(i));

+						}

+						sb.append("\n\t\tIssuer:        ");

+						sb.append(xc.getIssuerDN());

+						sb.append("\n\t\tNot Before:    ");

+						sb.append(xc.getNotBefore());

+						sb.append("\n\t\tNot After:     ");

+						sb.append(xc.getNotAfter());

+						sb.append("\n\t\tSigAlgorithm:  ");

+						sb.append(xc.getSigAlgName());

+						sb.append("\n\t\tType:          ");

+						sb.append(xc.getType());

+						sb.append("\n\t\tVersion:       ");

+						sb.append(xc.getVersion());

+

+						trustCerts.add(xc);

+					}

+				}

+			}

+			trans.init().log(sb);

+			// Add Additional ones from Property

+			String data_dir = trans.getProperty(AAF_DATA_DIR);

+			if(data_dir!=null) {

+				File data = new File(data_dir);

+				if(data.exists()) {

+					String trust_cas = trans.getProperty(CM_TRUST_CAS);

+					byte[] bytes;

+					if(trust_cas!=null) {

+						for(String fname : Split.split(';', trust_cas)) {

+							File crt = new File(data,fname);

+							if(crt.exists()) {

+								bytes = Factory.decode(crt);

+								try {

+									Collection<? extends Certificate> cc = Factory.toX509Certificate(bytes);

+									for(Certificate c : cc) {

+										trustCerts.add((X509Certificate)c);

+									}

+								} catch (CertificateException e) {

+									throw new CertException(e);

+								}

+							}

+						}

+					}

+				}

+			}

+			

+			String[] trustChain = new String[trustCerts.size()];

+			int i=-1;

+			for( Certificate cert : trustCerts) {

+				trustChain[++i]=BCFactory.toString(trans,cert);

+			}

+			

+			setTrustChain(trustChain);

+		} catch (ClientException | CertStoreException e) {

+			// Note:  Cannot validly start without all Clients, because we need to read all Issuing Certificates

+			// This is acceptable risk for most things, as we're not real time in general

+			throw new CertException(e);

+		}

+	}

+

+

+	@Override

+	public X509Certificate sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException {

+		TimeTaken tt = trans.start("Generating CSR and Keys for New Certificate", Env.SUB);

+		PKCS10CertificationRequest csr;

+		try {

+			csr = csrmeta.generateCSR(trans);

+			if(trans.info().isLoggable()) {

+				trans.info().log(BCFactory.toString(trans, csr));

+			} 

+			if(trans.info().isLoggable()) {

+				trans.info().log(csr);

+			}

+		} finally {

+			tt.done();

+		}

+		

+		tt = trans.start("Enroll CSR", Env.SUB);

+		Client client = null;

+		try {

+			client = clients.best();

+			EnrollmentResponse er = client.enrol(

+					csrmeta.initialConversationCert(trans),

+					csrmeta.keypair(trans).getPrivate(),

+					csr,

+					MS_PROFILE /* profile... MS can't deal with blanks*/);

+			while(true) {

+				if(er.isSuccess()) {

+					for( Certificate cert : er.getCertStore().getCertificates(null)) {

+						return (X509Certificate)cert;

+					}

+					break;

+				} else if (er.isPending()) {

+					trans.checkpoint("Polling, waiting on CA to complete");

+					Thread.sleep(3000);

+				} else if (er.isFailure()) {

+					throw new CertException(er.getFailInfo().toString());

+				}

+			}

+		} catch (ClientException e) {

+			trans.error().log(e,"SCEP Client Error, Temporarily Invalidating Client");

+			if(client!=null) {

+				clients.invalidate(client);

+			}

+		} catch (InterruptedException|TransactionException|CertificateException|OperatorCreationException | CertStoreException e) {

+			trans.error().log(e);

+		} finally {

+			tt.done();

+		}

+		

+		return null;

+	}

+

+

+	private class Clients implements Iterable<Client>{

+		/**

+		 * CSO Servers are in Dallas and St Louis

+		 * GEO_LOCATION   LATITUDE    LONGITUDE    ZIPCODE   TIMEZONE

+		 * ------------   --------    ---------    -------   --------

+		 * DLLSTXCF       32.779295   -96.800014   75202     America/Chicago

+		 * STLSMORC       38.627345   -90.193774   63101     America/Chicago

+		 * 

+		 * The online production issuing CA servers are:

+		 * 	AAF - CADI Issuing CA 01	135.41.45.152	MOSTLS1AAFXXA02

+		 * 	AAF - CADI Issuing CA 02	135.31.72.154	TXDLLS2AAFXXA02

+		 */

+		

+		private final Client[] client;

+		private final Date[] failure;

+		private int preferred;

+

+		public Clients(Trans trans, String urlstr) throws MalformedURLException { 

+	 		String[] urlstrs = Split.split(',', urlstr);

+	 		client = new Client[urlstrs.length];

+	 		failure = new Date[urlstrs.length];

+	 		double distance = Double.MAX_VALUE;

+	 		String localLat = trans.getProperty("AFT_LATITUDE","39.833333"); //Note: Defaulting to GEO center of US

+	 		String localLong = trans.getProperty("AFT_LONGITUDE","-98.583333");

+	 		for(int i=0;i<urlstrs.length;++i) {

+	 			String[] info = Split.split('/', urlstrs[i]);

+	 			if(info.length<3) {

+	 				throw new MalformedURLException("Configuration needs LAT and LONG, i.e. ip:port/lat/long");

+	 			}

+	 			client[i] = new Client(new URL(CA_PREFIX + info[0] + CA_POSTFIX), 

+		 			new CertificateVerifier() {

+		 				@Override

+		 				public boolean verify(X509Certificate cert) {

+		 					return true;

+		 				}

+		 			}

+	 			);

+	 			double d = GreatCircle.calc(info[1],info[2],localLat,localLong);

+	 			if(d<distance) {

+	 				preferred = i;

+	 				distance=d;

+	 			}

+	 		}

+	 		trans.init().printf("Preferred Certificate Authority is %s",urlstrs[preferred]);

+	 		for(int i=0;i<urlstrs.length;++i) {

+	 			if(i!=preferred) {

+	 				trans.init().printf("Alternate Certificate Authority is %s",urlstrs[i]);

+	 			}

+	 		}

+		}

+		private Client best() throws ClientException {

+			if(failure[preferred]==null) {

+				return client[preferred];

+			} else {

+				Client c=null;

+				// See if Alternate available

+				for(int i=0;i<failure.length;++i) {

+					if(failure[i]==null) {

+						c=client[i];

+					}

+				}

+				

+				// If not, see if any expirations can be cleared

+				Date now = new Date();

+				for(int i=0;i<failure.length;++i) {

+					if(now.after(failure[i])) {

+						failure[i]=null;

+						if(c==null) {

+							c=client[i];

+						}

+					}

+				}

+				

+				// if still nothing found, then throw.

+				if(c==null) {

+					throw new ClientException("No available machines to call");

+				} 

+				return c;

+			}

+		}

+		

+		public void invalidate(Client clt) {

+		   for(int i=0;i<client.length;++i) {

+			   if(client[i].equals(clt)) {

+				   failure[i]=new Date(System.currentTimeMillis()+180000 /* 3 mins */);

+			   }

+		   }

+		}

+		

+		@Override

+		public Iterator<Client> iterator() {

+			return new Iterator<Client>() {

+				private int iter = 0;

+				@Override

+				public boolean hasNext() {

+					return iter < Clients.this.client.length;

+				}

+

+				@Override

+				public Client next() {

+					return Clients.this.client[iter++];

+				}

+				

+			};

+		}

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/CA.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/CA.java
new file mode 100644
index 0000000..97b8a7b
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/CA.java
@@ -0,0 +1,84 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.ca;

+

+import java.io.IOException;

+import java.security.MessageDigest;

+import java.security.cert.X509Certificate;

+

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.authz.cm.cert.StandardFields;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.Trans;

+

+public abstract class CA {

+	private final String name;

+	private String[] trustChain;

+	private final StandardFields stdFields;

+	private MessageDigest messageDigest;

+	private final String permType;

+	

+	protected CA(String name, StandardFields sf, String permType) {

+		this.name = name;

+		stdFields = sf;

+		this.permType = permType;

+	}

+

+	/* 

+	 * NOTE: These two functions must be called in Protected Constructors during their Construction.

+	 */

+	protected void setTrustChain(String[] trustChain) {

+		this.trustChain = trustChain;

+	}

+

+	protected void setMessageDigest(MessageDigest md) {

+		messageDigest = md;

+	}

+

+	/*

+	 * End Required Constructor calls

+	 */

+

+	public String getName() {

+		return name;

+	}

+

+	public String[] getTrustChain() {

+		return trustChain;

+	}

+	

+	public String getPermType() {

+		return permType;

+	}

+	

+	public StandardFields stdFields() {

+		return stdFields;

+	}

+	

+	public abstract X509Certificate sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException;

+

+	public MessageDigest messageDigest() {

+		return messageDigest;

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/DevlCA.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/DevlCA.java
new file mode 100644
index 0000000..8edd287
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/ca/DevlCA.java
@@ -0,0 +1,226 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.ca;

+

+import java.io.File;

+import java.io.IOException;

+import java.math.BigInteger;

+import java.security.GeneralSecurityException;

+import java.security.KeyFactory;

+import java.security.cert.Certificate;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+import java.security.interfaces.RSAPrivateKey;

+import java.security.spec.PKCS8EncodedKeySpec;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.List;

+import java.security.SecureRandom;

+

+import org.bouncycastle.asn1.ASN1Sequence;

+import org.bouncycastle.asn1.x500.X500Name;

+import org.bouncycastle.asn1.x500.X500NameBuilder;

+import org.bouncycastle.asn1.x500.style.BCStyle;

+import org.bouncycastle.asn1.x509.BasicConstraints;

+import org.bouncycastle.asn1.x509.ExtendedKeyUsage;

+import org.bouncycastle.asn1.x509.Extension;

+import org.bouncycastle.asn1.x509.GeneralName;

+import org.bouncycastle.asn1.x509.GeneralNames;

+import org.bouncycastle.asn1.x509.KeyPurposeId;

+import org.bouncycastle.asn1.x509.KeyUsage;

+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;

+import org.bouncycastle.cert.X509v3CertificateBuilder;

+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;

+import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;

+import org.bouncycastle.operator.OperatorCreationException;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.authz.cm.cert.StandardFields;

+import org.onap.aaf.authz.common.Define;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+public class DevlCA extends CA {

+	

+	// Extensions

+	private static final KeyPurposeId[] ASN_WebUsage = new KeyPurposeId[] {

+				KeyPurposeId.id_kp_serverAuth, // WebServer

+				KeyPurposeId.id_kp_clientAuth};// WebClient

+				

+	private X509Certificate caCert;

+	private final RSAPrivateKey caKey;

+	private final X500Name issuer;

+	private final SecureRandom random = new SecureRandom();

+	private byte[] serialish = new byte[24];

+

+	public DevlCA(Trans trans, String name, String dirString) throws IOException, CertException {

+		super(name, new StandardFields() {

+			@Override

+			public void set(CSRMeta csr) {

+				// Standard Fields

+				csr.o("ATT Services, Inc.");

+				csr.l("St Louis");

+				csr.st("Missouri");

+				csr.c("US");

+			}

+		}, Define.ROOT_NS+".ca" // Permission Type for validation

+		);

+		File dir = new File(dirString);

+		if(!dir.exists()) {

+			throw new CertException(dirString + " does not exist");

+		}

+		

+		File ca = new File(dir,"ca.crt");

+		if(ca.exists()) {

+			byte[] bytes = Factory.decode(ca);

+			Collection<? extends Certificate> certs;

+			try {

+				certs = Factory.toX509Certificate(bytes);

+			} catch (CertificateException e) {

+				throw new CertException(e);

+			}

+			List<String> lTrust = new ArrayList<String>();

+			caCert=null;

+			for(Certificate c : certs) {

+				if(caCert==null) {

+					caCert = (X509Certificate)c;

+				} else {

+					lTrust.add(Factory.toString(trans,c));

+				}

+				break;

+			}

+		}

+		

+		this.setTrustChain(new String[]{Factory.toString(trans,caCert)});

+				

+			/*

+			 * Private key needs to be converted to "DER" format, with no password.  

+			 * 	Use chmod 400 on key

+			 * 

+			 *  openssl pkcs8 -topk8 -outform DER -nocrypt -in ca.key -out ca.der

+			 *

+			 */

+			ca = new File(dir,"ca.der");

+			if(ca.exists()) {

+				byte[] bytes = Factory.binary(ca);

+				

+//					EncryptedPrivateKeyInfo ekey=new EncryptedPrivateKeyInfo(bytes);

+//				    Cipher cip=Cipher.getInstance(ekey.getAlgName());

+//				    PBEKeySpec pspec=new PBEKeySpec("password".toCharArray());

+//				    SecretKeyFactory skfac=SecretKeyFactory.getInstance(ekey.getAlgName());

+//				    Key pbeKey=skfac.generateSecret(pspec);

+//				    AlgorithmParameters algParams=ekey.getAlgParameters();

+//				    cip.init(Cipher.DECRYPT_MODE,pbeKey,algParams);

+					

+				KeyFactory keyFactory;

+				try {

+					keyFactory = KeyFactory.getInstance("RSA");

+					PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(bytes);

+						

+		            caKey = (RSAPrivateKey) keyFactory.generatePrivate(privSpec);

+				} catch (GeneralSecurityException e) {

+					throw new CertException(e);

+				}

+				

+				X500NameBuilder xnb = new X500NameBuilder();

+				xnb.addRDN(BCStyle.C,"US");

+				xnb.addRDN(BCStyle.ST,"Missouri");

+				xnb.addRDN(BCStyle.L,"Arnold");

+				xnb.addRDN(BCStyle.O,"ATT Services, Inc.");

+				xnb.addRDN(BCStyle.OU,"AAF");

+				xnb.addRDN(BCStyle.CN,"aaf.att.com");

+				xnb.addRDN(BCStyle.EmailAddress,"DL-aaf-support@att.com");

+				issuer = xnb.build();

+		} else {

+			throw new CertException(ca.getPath() + " does not exist");

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.cm.service.CA#sign(org.bouncycastle.pkcs.PKCS10CertificationRequest)

+	 */

+	@Override

+	public X509Certificate sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException {

+		GregorianCalendar gc = new GregorianCalendar();

+		Date start = gc.getTime();

+		gc.add(GregorianCalendar.DAY_OF_MONTH, 1);

+		Date end = gc.getTime();

+		X509Certificate x509;

+		TimeTaken tt = trans.start("Create/Sign Cert",Env.SUB);

+		try {

+			BigInteger bi;

+			synchronized(serialish) {

+				random.nextBytes(serialish);

+				bi = new BigInteger(serialish);

+			}

+				

+			X509v3CertificateBuilder xcb = new X509v3CertificateBuilder(

+					issuer,

+					bi, // replace with Serialnumber scheme

+					start,

+					end,

+					csrmeta.x500Name(),

+//					SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(caCert.getPublicKey().getEn)

+					new SubjectPublicKeyInfo(ASN1Sequence.getInstance(caCert.getPublicKey().getEncoded()))

+					);

+			List<GeneralName> lsan = new ArrayList<GeneralName>();

+			for(String s : csrmeta.sans()) {

+				lsan.add(new GeneralName(GeneralName.dNSName,s));

+			}

+			GeneralName[] sans = new GeneralName[lsan.size()];

+			lsan.toArray(sans);

+

+		    JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();

+		    xcb		.addExtension(Extension.basicConstraints,

+                    	false, new BasicConstraints(false))

+		            .addExtension(Extension.keyUsage,

+		                true, new KeyUsage(KeyUsage.digitalSignature

+		                                 | KeyUsage.keyEncipherment))

+		            .addExtension(Extension.extendedKeyUsage,

+		                          true, new ExtendedKeyUsage(ASN_WebUsage))

+

+                    .addExtension(Extension.authorityKeyIdentifier,

+		                          false, extUtils.createAuthorityKeyIdentifier(caCert))

+		            .addExtension(Extension.subjectKeyIdentifier,

+		                          false, extUtils.createSubjectKeyIdentifier(caCert.getPublicKey()))

+		            .addExtension(Extension.subjectAlternativeName,

+		            		false, new GeneralNames(sans))

+		                                           ;

+	

+			x509 = new JcaX509CertificateConverter().getCertificate(

+					xcb.build(BCFactory.contentSigner(caKey)));

+		} catch (GeneralSecurityException|OperatorCreationException e) {

+			throw new CertException(e);

+		} finally {

+			tt.done();

+		}

+		return x509;

+	}

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/BCFactory.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/BCFactory.java
new file mode 100644
index 0000000..54a71f4
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/BCFactory.java
@@ -0,0 +1,168 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.cert;

+

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.lang.reflect.Field;

+import java.security.InvalidKeyException;

+import java.security.NoSuchAlgorithmException;

+import java.security.PrivateKey;

+import java.security.SignatureException;

+import java.util.List;

+

+import org.bouncycastle.asn1.ASN1Object;

+import org.bouncycastle.operator.ContentSigner;

+import org.bouncycastle.operator.OperatorCreationException;

+import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

+import org.bouncycastle.pkcs.PKCS10CertificationRequest;

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.validation.Validator;

+

+import org.onap.aaf.cadi.Symm;

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+

+/**

+ * Additional Factory mechanisms for CSRs, and BouncyCastle.  The main Factory

+ * utilizes only Java abstractions, and is useful in Client code.

+ * 

+

+ *

+ */

+public class BCFactory extends Factory {

+	private static final JcaContentSignerBuilder jcsb;

+

+

+	static {

+		// Bouncy

+		jcsb = new JcaContentSignerBuilder(Factory.SIG_ALGO);

+	}

+	

+	public static ContentSigner contentSigner(PrivateKey pk) throws OperatorCreationException {

+		return jcsb.build(pk);

+	}

+	

+	public static String toString(Trans trans, PKCS10CertificationRequest csr) throws IOException, CertException {

+		TimeTaken tt = trans.start("CSR to String", Env.SUB);

+		try {

+			if(csr==null) {

+				throw new CertException("x509 Certificate Request not built");

+			}

+			return textBuilder("CERTIFICATE REQUEST",csr.getEncoded());

+		}finally {

+			tt.done();

+		}

+	}

+

+	public static PKCS10CertificationRequest toCSR(Trans trans, File file) throws IOException {

+		TimeTaken tt = trans.start("Reconstitute CSR", Env.SUB);

+		try {

+			FileReader fr = new FileReader(file);

+			return new PKCS10CertificationRequest(decode(strip(fr)));

+		} finally {

+			tt.done();

+		}

+	}

+

+	public static byte[] sign(Trans trans, ASN1Object toSign, PrivateKey pk) throws IOException, InvalidKeyException, SignatureException, NoSuchAlgorithmException {

+		TimeTaken tt = trans.start("Encode Security Object", Env.SUB);

+		try {

+			return sign(trans,toSign.getEncoded(),pk);

+		} finally {

+			tt.done();

+		}

+	}

+

+	public static CSRMeta createCSRMeta(CA ca,final String args[]) throws IllegalArgumentException, IllegalAccessException, CertException {

+		CSRMeta csr = new CSRMeta();

+		ca.stdFields().set(csr);

+		//TODO should we checkDigest?

+//		digest = ca.messageDigest();

+

+		Field[] fld = CSRMeta.class.getDeclaredFields();

+		for(int i=0;i+1<args.length;++i) {

+			if(args[i].charAt(0)=='-') {

+				for(int j=0;j<fld.length;++j) {

+					if(fld[j].getType().equals(String.class) && args[i].substring(1).equals(fld[j].getName())) {

+						fld[j].set(csr,args[++i]);

+						break;

+					}

+				}

+			}

+		}

+		String errs = validate(csr);

+		if(errs!=null) {

+			throw new CertException(errs);

+		}

+		return csr;

+	}

+	

+	

+	public static CSRMeta createCSRMeta(CA ca, String mechid, String sponsorEmail, List<String> fqdns) throws CertException {

+		CSRMeta csr = new CSRMeta();

+		boolean first = true;

+		// Set CN (and SAN)

+		for(String fqdn : fqdns) {

+			if(first) {

+				first = false;

+				csr.cn(fqdn);

+			} else {

+				csr.san(fqdn);

+			}

+		}

+		

+		csr.challenge(new String(Symm.randomGen(24)));

+		ca.stdFields().set(csr);

+		csr.mechID(mechid);

+		csr.email(sponsorEmail);

+		String errs = validate(csr);

+		if(errs!=null) {

+			throw new CertException(errs);

+		}

+		return csr;

+	}

+

+	private static String validate(CSRMeta csr) {

+		Validator v = new Validator();

+		if(v.nullOrBlank("cn", csr.cn())

+			.nullOrBlank("mechID", csr.mechID())

+			.nullOrBlank("email", csr.email())

+			.nullOrBlank("o",csr.o())

+			.nullOrBlank("l",csr.l())

+			.nullOrBlank("st",csr.st())

+			.nullOrBlank("c",csr.c())

+			.err()) {

+			return v.errs();

+		} else {

+			return null;

+		}

+	}

+	

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/CSRMeta.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/CSRMeta.java
new file mode 100644
index 0000000..f71163e
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/CSRMeta.java
@@ -0,0 +1,329 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.cert;

+

+import java.io.IOException;

+import java.math.BigInteger;

+import java.security.KeyPair;

+import java.security.SecureRandom;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.List;

+

+import org.bouncycastle.asn1.ASN1Sequence;

+import org.bouncycastle.asn1.DERPrintableString;

+import org.bouncycastle.asn1.pkcs.Attribute;

+import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;

+import org.bouncycastle.asn1.x500.X500Name;

+import org.bouncycastle.asn1.x500.X500NameBuilder;

+import org.bouncycastle.asn1.x500.style.BCStyle;

+import org.bouncycastle.asn1.x509.Extension;

+import org.bouncycastle.asn1.x509.Extensions;

+import org.bouncycastle.asn1.x509.GeneralName;

+import org.bouncycastle.asn1.x509.GeneralNames;

+import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;

+import org.bouncycastle.cert.X509v3CertificateBuilder;

+import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;

+import org.bouncycastle.operator.OperatorCreationException;

+import org.bouncycastle.pkcs.PKCS10CertificationRequest;

+import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;

+import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.inno.env.Trans;

+

+public class CSRMeta {

+	private String environment;

+	private String cn;

+	private String mechID;

+	private String email;

+	private String o;

+	private String l;

+	private String st;

+	private String c;

+	private String challenge;

+	

+	private ArrayList<String> sanList = new ArrayList<String>();

+

+	private KeyPair keyPair;

+	private X500Name name = null;

+	private SecureRandom random = new SecureRandom();

+

+	public X500Name x500Name() throws IOException {

+		if(name==null) {

+			X500NameBuilder xnb = new X500NameBuilder();

+			xnb.addRDN(BCStyle.CN,cn);

+			xnb.addRDN(BCStyle.E,email);

+			if(environment==null) {

+				xnb.addRDN(BCStyle.OU,mechID);

+			} else {

+				xnb.addRDN(BCStyle.OU,mechID+':'+environment);

+			}

+			xnb.addRDN(BCStyle.O,o);

+			xnb.addRDN(BCStyle.L,l);

+			xnb.addRDN(BCStyle.ST,st);

+			xnb.addRDN(BCStyle.C,c);

+			name = xnb.build();

+		}

+		return name;

+	}

+	

+	

+	public PKCS10CertificationRequest  generateCSR(Trans trans) throws IOException, CertException {

+		PKCS10CertificationRequestBuilder builder = new JcaPKCS10CertificationRequestBuilder(x500Name(),keypair(trans).getPublic());

+		if(challenge!=null) {

+			DERPrintableString password = new DERPrintableString(challenge);

+			builder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_challengePassword, password);

+		}

+		

+		if(sanList.size()>0) {

+			GeneralName[] gna = new GeneralName[sanList.size()];

+			int i=-1;

+			for(String s : sanList) {

+				gna[++i]=new GeneralName(GeneralName.dNSName,s);

+			}

+			

+			builder.addAttribute(

+					PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,

+					new Extensions(new Extension[] {

+							new Extension(Extension.subjectAlternativeName,false,new GeneralNames(gna).getEncoded())

+					})

+			);

+		}

+//		builder.addAttribute(Extension.basicConstraints,new BasicConstraints(false))

+//      .addAttribute(Extension.keyUsage, new KeyUsage(KeyUsage.digitalSignature

+//                           | KeyUsage.keyEncipherment));

+		try {

+			return builder.build(BCFactory.contentSigner(keypair(trans).getPrivate()));

+		} catch (OperatorCreationException e) {

+			throw new CertException(e);

+		}

+	}

+	

+	@SuppressWarnings("deprecation")

+	public static void dump(PKCS10CertificationRequest csr) {

+		 Attribute[] certAttributes = csr.getAttributes();

+		 for (Attribute attribute : certAttributes) {

+		     if (attribute.getAttrType().equals(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest)) {

+		         Extensions extensions = Extensions.getInstance(attribute.getAttrValues().getObjectAt(0));

+//		         Extension ext = extensions.getExtension(Extension.subjectAlternativeName);

+		         GeneralNames gns = GeneralNames.fromExtensions(extensions,Extension.subjectAlternativeName);

+		         GeneralName[] names = gns.getNames();

+		         for(int k=0; k < names.length; k++) {

+		             String title = "";

+		             if(names[k].getTagNo() == GeneralName.dNSName) {

+		                 title = "dNSName";

+		             }

+		             else if(names[k].getTagNo() == GeneralName.iPAddress) {

+		                 title = "iPAddress";

+		                 // Deprecated, but I don't see anything better to use.

+		                 names[k].toASN1Object();

+		             }

+		             else if(names[k].getTagNo() == GeneralName.otherName) {

+		                 title = "otherName";

+		             }

+		             System.out.println(title + ": "+ names[k].getName());

+		         } 

+		     }

+		 }

+	}

+	

+	public X509Certificate initialConversationCert(Trans trans) throws IOException, CertificateException, OperatorCreationException {

+		GregorianCalendar gc = new GregorianCalendar();

+		Date start = gc.getTime();

+		gc.add(GregorianCalendar.DAY_OF_MONTH,2);

+		Date end = gc.getTime();

+		X509v3CertificateBuilder xcb = new X509v3CertificateBuilder(

+				x500Name(),

+				new BigInteger(12,random), // replace with Serialnumber scheme

+				start,

+				end,

+				x500Name(),

+//				SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(caCert.getPublicKey().getEn)

+				new SubjectPublicKeyInfo(ASN1Sequence.getInstance(keypair(trans).getPublic().getEncoded()))

+				);

+		return new JcaX509CertificateConverter().getCertificate(

+				xcb.build(BCFactory.contentSigner(keypair(trans).getPrivate())));

+	}

+

+	public CSRMeta san(String v) {

+		sanList.add(v);

+		return this;

+	}

+

+	public List<String> sans() {

+		return sanList;

+	}

+

+

+	public KeyPair keypair(Trans trans) {

+		if(keyPair == null) {

+			keyPair = Factory.generateKeyPair(trans);

+		}

+		return keyPair;

+	}

+

+	/**

+	 * @return the cn

+	 */

+	public String cn() {

+		return cn;

+	}

+

+

+	/**

+	 * @param cn the cn to set

+	 */

+	public void cn(String cn) {

+		this.cn = cn;

+	}

+

+	/**

+	 * Environment of Service MechID is good for

+	 */

+	public void environment(String env) {

+		environment = env;

+	}

+	

+	/**

+	 * 

+	 * @return

+	 */

+	public String environment() {

+		return environment;

+	}

+	

+	/**

+	 * @return the mechID

+	 */

+	public String mechID() {

+		return mechID;

+	}

+

+

+	/**

+	 * @param mechID the mechID to set

+	 */

+	public void mechID(String mechID) {

+		this.mechID = mechID;

+	}

+

+

+	/**

+	 * @return the email

+	 */

+	public String email() {

+		return email;

+	}

+

+

+	/**

+	 * @param email the email to set

+	 */

+	public void email(String email) {

+		this.email = email;

+	}

+

+

+	/**

+	 * @return the o

+	 */

+	public String o() {

+		return o;

+	}

+

+

+	/**

+	 * @param o the o to set

+	 */

+	public void o(String o) {

+		this.o = o;

+	}

+

+	/**

+	 * 

+	 * @return the l

+	 */

+	public String l() {

+		return l;

+	}

+	

+	/**

+	 * @param l the l to set

+	 */

+	public void l(String l) {

+		this.l=l;

+	}

+

+	/**

+	 * @return the st

+	 */

+	public String st() {

+		return st;

+	}

+

+

+	/**

+	 * @param st the st to set

+	 */

+	public void st(String st) {

+		this.st = st;

+	}

+

+

+	/**

+	 * @return the c

+	 */

+	public String c() {

+		return c;

+	}

+

+

+	/**

+	 * @param c the c to set

+	 */

+	public void c(String c) {

+		this.c = c;

+	}

+

+

+	/**

+	 * @return the challenge

+	 */

+	public String challenge() {

+		return challenge;

+	}

+

+

+	/**

+	 * @param challenge the challenge to set

+	 */

+	public void challenge(String challenge) {

+		this.challenge = challenge;

+	}

+	

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/StandardFields.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/StandardFields.java
new file mode 100644
index 0000000..f298d0d
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/cert/StandardFields.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.cert;

+

+import org.onap.aaf.cadi.cm.CertException;

+

+public interface StandardFields {

+	public void set(CSRMeta csr) throws CertException;

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertDrop.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertDrop.java
new file mode 100644
index 0000000..03906c0
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertDrop.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.data;

+

+public class CertDrop {

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertRenew.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertRenew.java
new file mode 100644
index 0000000..a0eb306
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertRenew.java
@@ -0,0 +1,27 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.data;

+

+public class CertRenew {

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertReq.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertReq.java
new file mode 100644
index 0000000..668686a
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertReq.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.data;

+

+import java.util.List;

+

+import javax.xml.datatype.XMLGregorianCalendar;

+

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+

+import org.onap.aaf.cadi.cm.CertException;

+

+public class CertReq {

+	// These cannot be null

+	public CA certAuthority;

+	public String mechid;

+	public List<String> fqdns;

+	// Notify

+	public List<String> emails;

+	

+	

+	// These may be null

+	public String sponsor;

+	public XMLGregorianCalendar start, end;

+	

+	public CSRMeta getCSRMeta() throws CertException {

+		return BCFactory.createCSRMeta(certAuthority, mechid, sponsor,fqdns);

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertResp.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertResp.java
new file mode 100644
index 0000000..d06f63b
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/data/CertResp.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.data;

+

+import java.io.IOException;

+import java.security.GeneralSecurityException;

+import java.security.KeyPair;

+import java.security.cert.X509Certificate;

+

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.inno.env.Trans;

+

+public class CertResp {

+	public CertResp(Trans trans, X509Certificate x509, CSRMeta csrMeta, String[] notes) throws IOException, GeneralSecurityException, CertException {

+		keyPair = csrMeta.keypair(trans);

+		privateKey = Factory.toString(trans, keyPair.getPrivate());

+		certString = Factory.toString(trans,x509);

+		challenge=csrMeta.challenge();

+		this.notes = notes;

+	}

+	private KeyPair keyPair;

+	private String challenge;

+	

+	private String privateKey, certString;

+	private String[] notes;

+	

+	

+	public String asCertString() {

+		return certString;

+	}

+	

+	public String privateString() throws IOException {

+		return privateKey;

+	}

+	

+	public String challenge() {

+		return challenge==null?"":challenge;

+	}

+	

+	public String[] notes() {

+		return notes;

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade.java
new file mode 100644
index 0000000..a5c8c65
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade.java
@@ -0,0 +1,161 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.facade;

+

+import java.io.IOException;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.cm.mapper.Mapper;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+

+

+/**

+ *   

+ *

+ */

+public interface Facade<REQ,CERT,ARTIFACTS,ERROR> {

+

+/////////////////////  STANDARD ELEMENTS //////////////////

+	/** 

+	 * @param trans

+	 * @param response

+	 * @param result

+	 */

+	void error(AuthzTrans trans, HttpServletResponse response, Result<?> result);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param response

+	 * @param status

+	 */

+	void error(AuthzTrans trans, HttpServletResponse response, int status,	String msg, String ... detail);

+

+	/**

+	 * Permission checker

+	 *

+	 * @param trans

+	 * @param resp

+	 * @param perm

+	 * @return

+	 * @throws IOException 

+	 */

+	Result<Void> check(AuthzTrans trans, HttpServletResponse resp, String perm) throws IOException;

+

+	/**

+	 * 

+	 * @return

+	 */

+	public Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper();

+

+/////////////////////  STANDARD ELEMENTS //////////////////

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param resp

+	 * @param rservlet

+	 * @return

+	 */

+	public abstract Result<Void> requestCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	public abstract Result<Void> renewCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	public abstract Result<Void> dropCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	Result<Void> createArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	Result<Void> readArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param resp

+	 * @param mechid

+	 * @param machine

+	 * @return

+	 */

+	Result<Void> readArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	Result<Void> updateArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param resp

+	 * @return

+	 */

+	Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param resp

+	 * @param mechid

+	 * @param machine

+	 * @return

+	 */

+	Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine);

+

+

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade1_0.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade1_0.java
new file mode 100644
index 0000000..525b38a
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/Facade1_0.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.facade;

+

+import org.onap.aaf.authz.cm.mapper.Mapper;

+import org.onap.aaf.authz.cm.service.CMService;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+import aaf.v2_0.Error;

+import certman.v1_0.Artifacts;

+import certman.v1_0.BaseRequest;

+import certman.v1_0.CertInfo;

+

+/**

+ *

+ */

+public class Facade1_0 extends FacadeImpl<BaseRequest,CertInfo, Artifacts, Error> {

+	public Facade1_0(CertManAPI certman, 

+					 CMService service, 

+					 Mapper<BaseRequest,CertInfo,Artifacts,Error> mapper, 

+					 Data.TYPE type) throws APIException {

+		super(certman, service, mapper, type);

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeFactory.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeFactory.java
new file mode 100644
index 0000000..0c19837
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeFactory.java
@@ -0,0 +1,43 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.facade;

+

+import org.onap.aaf.authz.cm.mapper.Mapper1_0;

+import org.onap.aaf.authz.cm.service.CMService;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.env.AuthzTrans;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+

+public class FacadeFactory {

+	public static Facade1_0 v1_0(CertManAPI certman, AuthzTrans trans, CMService service, Data.TYPE type) throws APIException {

+		return new Facade1_0(

+				certman,

+				service,

+				new Mapper1_0(),

+				type);  

+	}

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeImpl.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeImpl.java
new file mode 100644
index 0000000..468aacd
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/facade/FacadeImpl.java
@@ -0,0 +1,493 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.facade;

+

+import static org.onap.aaf.authz.layer.Result.ERR_ActionNotCompleted;

+import static org.onap.aaf.authz.layer.Result.ERR_BadData;

+import static org.onap.aaf.authz.layer.Result.ERR_ConflictAlreadyExists;

+import static org.onap.aaf.authz.layer.Result.ERR_Denied;

+import static org.onap.aaf.authz.layer.Result.ERR_NotFound;

+import static org.onap.aaf.authz.layer.Result.ERR_NotImplemented;

+import static org.onap.aaf.authz.layer.Result.ERR_Policy;

+import static org.onap.aaf.authz.layer.Result.ERR_Security;

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import java.io.IOException;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.cm.api.API_Cert;

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.data.CertResp;

+import org.onap.aaf.authz.cm.mapper.Mapper;

+import org.onap.aaf.authz.cm.mapper.Mapper.API;

+import org.onap.aaf.authz.cm.service.CMService;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import org.onap.aaf.cadi.aaf.AAFPermission;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.util.Split;

+import org.onap.aaf.rosetta.env.RosettaDF;

+import org.onap.aaf.rosetta.env.RosettaData;

+

+/**

+ * AuthzFacade

+ * 

+ * This Service Facade encapsulates the essence of the API Service can do, and provides

+ * a single created object for elements such as RosettaDF.

+ *

+ * The Responsibilities of this class are to:

+ * 1) Interact with the Service Implementation (which might be supported by various kinds of Backend Storage)

+ * 2) Validate incoming data (if applicable)

+ * 3) Convert the Service response into the right Format, and mark the Content Type

+ * 		a) In the future, we may support multiple Response Formats, aka JSON or XML, based on User Request.

+ * 4) Log Service info, warnings and exceptions as necessary

+ * 5) When asked by the API layer, this will create and write Error content to the OutputStream

+ * 

+ * Note: This Class does NOT set the HTTP Status Code.  That is up to the API layer, so that it can be 

+ * clearly coordinated with the API Documentation

+ * 

+ *

+ */

+public abstract class FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> extends org.onap.aaf.authz.layer.FacadeImpl implements Facade<REQ,CERT,ARTIFACTS,ERROR> 

+	{

+	private static final String REQUEST_CERT = "Request New Certificate";

+	private static final String RENEW_CERT = "Renew Certificate";

+	private static final String DROP_CERT = "Drop Certificate";

+	private static final String CREATE_ARTIFACTS = "Create Deployment Artifact";

+	private static final String READ_ARTIFACTS = "Read Deployment Artifact";

+	private static final String UPDATE_ARTIFACTS = "Update Deployment Artifact";

+	private static final String DELETE_ARTIFACTS = "Delete Deployment Artifact";

+

+	private CMService service;

+

+	private final RosettaDF<ERROR>	 	errDF;

+	private final RosettaDF<REQ> 		certRequestDF, certRenewDF, certDropDF;

+	private final RosettaDF<CERT>		certDF;

+	private final RosettaDF<ARTIFACTS>	artiDF;

+	private Mapper<REQ, CERT, ARTIFACTS, ERROR> 	mapper;

+	private Slot sCertAuth;

+	private CertManAPI certman;

+	private final String voidResp;

+

+	public FacadeImpl(CertManAPI certman,

+					  CMService service, 

+					  Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper, 

+					  Data.TYPE dataType) throws APIException {

+		this.service = service;

+		this.mapper = mapper;

+		this.certman = certman;

+		AuthzEnv env = certman.env;

+		(errDF 				= env.newDataFactory(mapper.getClass(API.ERROR))).in(dataType).out(dataType);

+		(certRequestDF 		= env.newDataFactory(mapper.getClass(API.CERT_REQ))).in(dataType).out(dataType);

+		(certRenewDF 		= env.newDataFactory(mapper.getClass(API.CERT_RENEW))).in(dataType).out(dataType);

+		(certDropDF 		= env.newDataFactory(mapper.getClass(API.CERT_DROP))).in(dataType).out(dataType);

+		(certDF 			= env.newDataFactory(mapper.getClass(API.CERT))).in(dataType).out(dataType);

+		(artiDF 			= env.newDataFactory(mapper.getClass(API.ARTIFACTS))).in(dataType).out(dataType);

+		sCertAuth = env.slot(API_Cert.CERT_AUTH);

+		if(artiDF.getOutType().name().contains("xml")) {

+			voidResp = "application/Void+xml;charset=utf-8;version=1.0,application/xml;version=1.0,*/*";

+		} else {

+			voidResp = "application/Void+json;charset=utf-8;version=1.0,application/json;version=1.0,*/*";

+		}

+	}

+	

+	public Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper() {

+		return mapper;

+	}

+	

+	/* (non-Javadoc)

+	 * @see com.att.authz.facade.AuthzFacade#error(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, int)

+	 * 

+	 * Note: Conforms to AT&T TSS RESTful Error Structure

+	 */

+	@Override

+	public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {

+		error(trans, response, result.status,

+				result.details==null?"":result.details.trim(),

+				result.variables==null?new String[0]:result.variables);

+	}

+		

+	@Override

+	public void error(AuthzTrans trans, HttpServletResponse response, int status, final String _msg, final String ... _detail) {

+		String msgId;

+		String prefix;

+		switch(status) {

+			case 202:

+			case ERR_ActionNotCompleted:

+				msgId = "SVC1202";

+				prefix = "Accepted, Action not complete";

+				response.setStatus(/*httpstatus=*/202);

+				break;

+

+			case 403:

+			case ERR_Policy:

+			case ERR_Security:

+			case ERR_Denied:

+				msgId = "SVC1403";

+				prefix = "Forbidden";

+				response.setStatus(/*httpstatus=*/403);

+				break;

+				

+			case 404:

+			case ERR_NotFound:

+				msgId = "SVC1404";

+				prefix = "Not Found";

+				response.setStatus(/*httpstatus=*/404);

+				break;

+

+			case 406:

+			case ERR_BadData:

+				msgId="SVC1406";

+				prefix = "Not Acceptable";

+				response.setStatus(/*httpstatus=*/406);

+				break;

+				

+			case 409:

+			case ERR_ConflictAlreadyExists:

+				msgId = "SVC1409";

+				prefix = "Conflict Already Exists";

+				response.setStatus(/*httpstatus=*/409);

+				break;

+			

+			case 501:

+			case ERR_NotImplemented:

+				msgId = "SVC1501";

+				prefix = "Not Implemented"; 

+				response.setStatus(/*httpstatus=*/501);

+				break;

+				

+

+			default:

+				msgId = "SVC1500";

+				prefix = "General Service Error";

+				response.setStatus(/*httpstatus=*/500);

+				break;

+		}

+

+		try {

+			StringBuilder holder = new StringBuilder();

+			errDF.newData(trans).load(

+				mapper().errorFromMessage(holder, msgId,prefix + ": " + _msg,_detail)).to(response.getOutputStream());

+			

+			holder.append(']');

+			trans.checkpoint(

+					"ErrResp [" + 

+					holder,

+					Env.ALWAYS);

+		} catch (Exception e) {

+			trans.error().log(e,"unable to send response for",_msg);

+		}

+	}

+

+	@Override

+	public Result<Void> check(AuthzTrans trans, HttpServletResponse resp, String perm) throws IOException {

+		String[] p = Split.split('|',perm);

+		if(p.length!=3) {

+			return Result.err(Result.ERR_BadData,"Invalid Perm String");

+		}

+		AAFPermission ap = new AAFPermission(p[0],p[1],p[2]);

+		if(certman.aafLurPerm.fish(trans.getUserPrincipal(), ap)) {

+			resp.setContentType(voidResp);

+			resp.getOutputStream().write(0);

+			return Result.ok();

+		} else {

+			return Result.err(Result.ERR_Denied,"%s does not have %s",trans.user(),ap.getKey());

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.auth.certman.facade.Facade#requestCert(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

+	 */

+	@Override

+	public Result<Void> requestCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust) {

+		TimeTaken tt = trans.start(REQUEST_CERT, Env.SUB|Env.ALWAYS);

+		try {

+			REQ request;

+			try {

+				Data<REQ> rd = certRequestDF.newData().load(req.getInputStream());

+				request = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,REQUEST_CERT);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<CertResp> rcr = service.requestCert(trans,mapper.toReq(trans,request));

+			if(rcr.notOK()) {

+				return Result.err(rcr);

+			}

+			

+			CA certAuth = trans.get(sCertAuth,null);

+			Result<CERT> rc = mapper.toCert(trans, rcr, withTrust?certAuth.getTrustChain():null);

+			switch(rc.status) {

+			case OK: 

+				RosettaData<CERT> data = certDF.newData(trans).load(rc.value);

+				data.to(resp.getOutputStream());

+

+				setContentType(resp,certDF.getOutType());

+				return Result.ok();

+			default:

+				return Result.err(rc);

+		}

+

+		} catch (Exception e) {

+			trans.error().log(e,IN,REQUEST_CERT);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> renewCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, boolean withTrust) {

+		TimeTaken tt = trans.start(RENEW_CERT, Env.SUB|Env.ALWAYS);

+		try {

+			REQ request;

+			try {

+				Data<REQ> rd = certRenewDF.newData().load(req.getInputStream());

+				request = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,RENEW_CERT);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			String certAuth = trans.get(sCertAuth,null);

+			Result<CertResp> rcr = service.renewCert(trans,mapper.toRenew(trans,request));

+			Result<CERT> rc = mapper.toCert(trans, rcr, certman.getTrustChain(certAuth));

+

+			switch(rc.status) {

+				case OK: 

+					RosettaData<CERT> data = certDF.newData(trans).load(rc.value);

+					data.to(resp.getOutputStream());

+

+					setContentType(resp,certDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rc);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,RENEW_CERT);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+

+	}

+

+	@Override

+	public Result<Void> dropCert(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DROP_CERT, Env.SUB|Env.ALWAYS);

+		try {

+			REQ request;

+			try {

+				Data<REQ> rd = certDropDF.newData().load(req.getInputStream());

+				request = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,DROP_CERT);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rv = service.dropCert(trans,mapper.toDrop(trans, request));

+			switch(rv.status) {

+				case OK: 

+					setContentType(resp,certRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rv);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DROP_CERT);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	////////////////////////////

+	// Artifacts

+	////////////////////////////

+	@Override

+	public Result<Void> createArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(CREATE_ARTIFACTS, Env.SUB);

+		try {

+			ARTIFACTS arti;

+			try {

+				Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());

+				arti = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_ARTIFACTS);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			return service.createArtifact(trans,mapper.toArtifact(trans,arti));

+		} catch (Exception e) {

+

+			trans.error().log(e,IN,CREATE_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> readArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(READ_ARTIFACTS, Env.SUB);

+		try {

+			String mechid = req.getParameter("mechid");

+			String machine = req.getParameter("machine");

+			

+			Result<ARTIFACTS> ra;

+			if( machine !=null && mechid == null) {

+				ra = mapper.fromArtifacts(service.readArtifactsByMachine(trans, machine));

+			} else if(mechid!=null && machine==null) {

+				ra = mapper.fromArtifacts(service.readArtifactsByMechID(trans, mechid));

+			} else if(mechid!=null && machine!=null) {

+				ArtiDAO.Data add = new ArtiDAO.Data();

+				add.mechid = mechid;

+				add.machine = machine;

+				ra = mapper.fromArtifacts(service.readArtifacts(trans,add));

+			} else {

+				ra = Result.err(Status.ERR_BadData,"Invalid request inputs");

+			}

+			

+			if(ra.isOK()) {

+				RosettaData<ARTIFACTS> data = artiDF.newData(trans).load(ra.value);

+				data.to(resp.getOutputStream());

+				setContentType(resp,artiDF.getOutType());

+				return Result.ok();

+			} else {

+				return Result.err(ra);

+			}

+

+		} catch (Exception e) {

+			trans.error().log(e,IN,READ_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> readArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine) {

+		TimeTaken tt = trans.start(READ_ARTIFACTS, Env.SUB);

+		try {

+			ArtiDAO.Data add = new ArtiDAO.Data();

+			add.mechid = mechid;

+			add.machine = machine;

+			Result<ARTIFACTS> ra = mapper.fromArtifacts(service.readArtifacts(trans,add));

+			if(ra.isOK()) {

+				RosettaData<ARTIFACTS> data = artiDF.newData(trans).load(ra.value);

+				data.to(resp.getOutputStream());

+				setContentType(resp,artiDF.getOutType());

+				return Result.ok();

+			} else {

+				return Result.err(ra);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,READ_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+

+	@Override

+	public Result<Void> updateArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_ARTIFACTS, Env.SUB);

+		try {

+			ARTIFACTS arti;

+			try {

+				Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());

+				arti = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,UPDATE_ARTIFACTS);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			return service.updateArtifact(trans,mapper.toArtifact(trans,arti));

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DELETE_ARTIFACTS, Env.SUB);

+		try {

+			ARTIFACTS arti;

+			try {

+				Data<ARTIFACTS> rd = artiDF.newData().load(req.getInputStream());

+				arti = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,DELETE_ARTIFACTS);

+				return Result.err(Result.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rv = service.deleteArtifact(trans,mapper.toArtifact(trans,arti));

+			switch(rv.status) {

+				case OK: 

+					setContentType(resp,artiDF.getOutType());

+			} 

+			return rv;

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deleteArtifacts(AuthzTrans trans, HttpServletResponse resp, String mechid, String machine) {

+		TimeTaken tt = trans.start(DELETE_ARTIFACTS, Env.SUB);

+		try {

+			Result<Void> rv = service.deleteArtifact(trans, mechid, machine);

+			switch(rv.status) {

+				case OK: 

+					setContentType(resp,artiDF.getOutType());

+			} 

+			return rv;

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_ARTIFACTS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper.java
new file mode 100644
index 0000000..a04ac25
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.mapper;

+

+import java.io.IOException;

+import java.util.List;

+

+import org.onap.aaf.authz.cm.data.CertDrop;

+import org.onap.aaf.authz.cm.data.CertRenew;

+import org.onap.aaf.authz.cm.data.CertReq;

+import org.onap.aaf.authz.cm.data.CertResp;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+

+public interface Mapper<REQ,CERT,ARTIFACTS,ERROR>

+{

+	public enum API{ERROR,VOID,CERT,CERT_REQ,CERT_RENEW,CERT_DROP,ARTIFACTS};

+	

+	public Class<?> getClass(API api);

+	public<A> A newInstance(API api);

+

+	public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, String... detail);

+	

+	public Result<CERT> toCert(AuthzTrans trans, Result<CertResp> in, String[] trustChain) throws IOException;

+	public Result<CertReq> toReq(AuthzTrans trans, REQ req);

+	public Result<CertRenew> toRenew(AuthzTrans trans, REQ req);

+	public Result<CertDrop>  toDrop(AuthzTrans trans, REQ req);

+	

+	public List<ArtiDAO.Data> toArtifact(AuthzTrans trans, ARTIFACTS arti);

+	public Result<ARTIFACTS> fromArtifacts(Result<List<ArtiDAO.Data>> readArtifactsByMachine);

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper1_0.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper1_0.java
new file mode 100644
index 0000000..2cb861c
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/mapper/Mapper1_0.java
@@ -0,0 +1,246 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.mapper;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.onap.aaf.authz.cm.data.CertDrop;

+import org.onap.aaf.authz.cm.data.CertRenew;

+import org.onap.aaf.authz.cm.data.CertReq;

+import org.onap.aaf.authz.cm.data.CertResp;

+import org.onap.aaf.authz.cm.validation.Validator;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO.Data;

+

+import aaf.v2_0.Error;

+import certman.v1_0.Artifacts;

+import certman.v1_0.Artifacts.Artifact;

+import certman.v1_0.BaseRequest;

+import certman.v1_0.CertInfo;

+import certman.v1_0.CertificateDrop;

+import certman.v1_0.CertificateRenew;

+import certman.v1_0.CertificateRequest;

+

+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;

+import org.onap.aaf.cadi.util.Vars;

+

+

+public class Mapper1_0 implements Mapper<BaseRequest,CertInfo,Artifacts,Error> {

+	

+	@Override

+	public Class<?> getClass(API api) {

+		switch(api) {

+			case CERT_REQ: return CertificateRequest.class;

+			case CERT_RENEW: return CertificateRenew.class;

+			case CERT_DROP: return CertificateDrop.class;

+			case CERT: return CertInfo.class;

+			case ARTIFACTS: return Artifacts.class;

+			case ERROR: return Error.class;

+			case VOID: return Void.class;

+		}

+		return null;

+	}

+

+	@SuppressWarnings("unchecked")

+	@Override

+	public <A> A newInstance(API api) {

+		switch(api) {

+			case CERT_REQ: return (A) new CertificateRequest();

+			case CERT_RENEW: return (A) new CertificateRenew();

+			case CERT_DROP: return (A) new CertificateDrop();

+			case CERT: return (A) new CertInfo();

+			case ARTIFACTS: return (A) new Artifacts();

+			case ERROR: return (A)new Error();

+			case VOID: return null;

+		}

+		return null;

+	}

+

+	//////////////  Mapping Functions /////////////

+	@Override

+	public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {

+		Error err = new Error();

+		err.setMessageId(msgID);

+		// AT&T Restful Error Format requires numbers "%" placements

+		err.setText(Vars.convert(holder, text, var));

+		for(String s : var) {

+			err.getVariables().add(s);

+		}

+		return err;

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.authz.certman.mapper.Mapper#toCert(org.onap.aaf.authz.env.AuthzTrans, org.onap.aaf.authz.layer.Result)

+	 */

+	@Override

+	public Result<CertInfo> toCert(AuthzTrans trans, Result<CertResp> in, String[] trustChain) throws IOException {

+		if(in.isOK()) {

+			CertResp cin = in.value;

+			CertInfo cout = newInstance(API.CERT);

+			cout.setPrivatekey(cin.privateString());

+			String value;

+			if((value=cin.challenge())!=null) {

+				cout.setChallenge(value);

+			}

+			cout.getCerts().add(cin.asCertString());

+			if(trustChain!=null) {

+				for(String c : trustChain) {

+					cout.getCerts().add(c);

+				}

+			}

+			if(cin.notes()!=null) {

+				boolean first = true;

+				StringBuilder sb = new StringBuilder();

+				for(String n : cin.notes()) {

+					if(first) {

+						first = false;

+					} else {

+						sb.append('\n');

+					}

+					sb.append(n);

+				}

+				cout.setNotes(sb.toString());

+			}

+			return Result.ok(cout);

+		} else {

+			return Result.err(in);

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.authz.certman.mapper.Mapper#toReq(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object)

+	 */

+	@Override

+	public Result<CertReq> toReq(AuthzTrans trans, BaseRequest req) {

+		CertificateRequest in;

+		try {

+			in = (CertificateRequest)req;

+		} catch(ClassCastException e) {

+			return Result.err(Result.ERR_BadData,"Request is not a CertificateRequest");

+		}

+

+		CertReq out = new CertReq();

+		Validator v = new Validator();

+		if(v.isNull("CertRequest", req)

+			.nullOrBlank("MechID", out.mechid=in.getMechid())

+			.nullBlankMin("FQDNs", out.fqdns=in.getFqdns(),1)

+			.err()) {

+			return Result.err(Result.ERR_BadData, v.errs());

+		}

+		out.emails = in.getEmail();

+		out.sponsor=in.getSponsor();

+		out.start = in.getStart();

+		out.end = in.getEnd();

+		return Result.ok(out);

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.authz.certman.mapper.Mapper#toRenew(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object)

+	 */

+	@Override

+	public Result<CertRenew> toRenew(AuthzTrans trans, BaseRequest req) {

+		return Result.err(Result.ERR_NotImplemented,"Not Implemented... yet");

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.authz.certman.mapper.Mapper#toDrop(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object)

+	 */

+	@Override

+	public Result<CertDrop> toDrop(AuthzTrans trans, BaseRequest req) {

+		return Result.err(Result.ERR_NotImplemented,"Not Implemented... yet");

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.cm.mapper.Mapper#toArtifact(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object)

+	 */

+	@Override

+	public List<ArtiDAO.Data> toArtifact(AuthzTrans trans, Artifacts artifacts) {

+		List<ArtiDAO.Data> ladd = new ArrayList<ArtiDAO.Data>();

+		for(Artifact arti : artifacts.getArtifact()) {

+			ArtiDAO.Data data = new ArtiDAO.Data();

+			data.mechid = arti.getMechid();

+			data.machine = arti.getMachine();

+			data.type(true).addAll(arti.getType());

+			data.ca = arti.getCa();

+			data.dir = arti.getDir();

+			data.os_user = arti.getOsUser();

+			// Optional (on way in)

+			data.appName = arti.getAppName();

+			data.renewDays = arti.getRenewDays();

+			data.notify = arti.getNotification();

+			

+			// Ignored on way in for create/update

+			data.sponsor = arti.getSponsor();

+			data.expires = null;

+			

+			// Derive Optional Data from Machine (Domain) if exists

+			if(data.machine!=null) {

+				if(data.ca==null) {

+					if(data.machine.endsWith(".att.com")) {

+						data.ca = "aaf"; // default

+					}

+				}

+				if(data.appName==null ) {

+					data.appName=AAFCon.reverseDomain(data.machine);

+				}

+			}

+

+			ladd.add(data);

+		}

+		return ladd;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.cm.mapper.Mapper#fromArtifacts(org.onap.aaf.authz.layer.Result)

+	 */

+	@Override

+	public Result<Artifacts> fromArtifacts(Result<List<Data>> lArtiDAO) {

+		if(lArtiDAO.isOK()) {

+			Artifacts artis = new Artifacts();

+			for(ArtiDAO.Data arti : lArtiDAO.value) {

+				Artifact a = new Artifact();

+				a.setMechid(arti.mechid);

+				a.setMachine(arti.machine);

+				a.setSponsor(arti.sponsor);

+				a.setAppName(arti.appName);

+				a.setCa(arti.ca);

+				a.setDir(arti.dir);

+				a.getType().addAll(arti.type(false));

+				a.setOsUser(arti.os_user);

+				a.setRenewDays(arti.renewDays);

+				a.setNotification(arti.notify);

+				artis.getArtifact().add(a);

+			}

+			return Result.ok(artis);

+		} else {

+			return Result.err(lArtiDAO);

+		}

+	}

+	

+	

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CMService.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CMService.java
new file mode 100644
index 0000000..9924973
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CMService.java
@@ -0,0 +1,515 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.service;

+

+import java.io.IOException;

+import java.net.InetAddress;

+import java.net.UnknownHostException;

+import java.nio.ByteBuffer;

+import java.security.NoSuchAlgorithmException;

+import java.security.cert.X509Certificate;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.List;

+

+import org.onap.aaf.authz.cm.api.API_Cert;

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.authz.cm.data.CertDrop;

+import org.onap.aaf.authz.cm.data.CertRenew;

+import org.onap.aaf.authz.cm.data.CertReq;

+import org.onap.aaf.authz.cm.data.CertResp;

+import org.onap.aaf.authz.cm.validation.Validator;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.DAO;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+import org.onap.aaf.dao.aaf.cass.CacheInfoDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.cadi.Hash;

+import org.onap.aaf.cadi.aaf.AAFPermission;

+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;

+import org.onap.aaf.cadi.cm.Factory;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.util.Chrono;

+import com.datastax.driver.core.Cluster;

+

+

+public class CMService {

+	// If we add more CAs, may want to parameterize

+	private static final int STD_RENEWAL = 30;

+	private static final int MAX_RENEWAL = 60;

+	private static final int MIN_RENEWAL = 10;

+	

+	public static final String REQUEST = "request";

+	public static final String RENEW = "renew";

+	public static final String DROP = "drop";

+	public static final String SANS = "san";

+	

+	private static final String[] NO_NOTES = new String[0];

+	private Slot sCertAuth;

+	private final CertDAO certDAO;

+	private final CredDAO credDAO;

+	private final ArtiDAO artiDAO;

+	private DAO<AuthzTrans, ?>[] daos;

+

+	@SuppressWarnings("unchecked")

+	public CMService(AuthzTrans trans, CertManAPI certman) throws APIException, IOException {

+

+		sCertAuth = certman.env.slot(API_Cert.CERT_AUTH);

+		Cluster cluster;

+		try {

+			cluster = org.onap.aaf.dao.CassAccess.cluster(certman.env,null);

+		} catch (IOException e) {

+			throw new APIException(e);

+		}

+

+		// jg 4/2015 SessionFilter unneeded... DataStax already deals with Multithreading well

+		

+		HistoryDAO hd = new HistoryDAO(trans,  cluster, CassAccess.KEYSPACE);

+		CacheInfoDAO cid = new CacheInfoDAO(trans, hd);

+		certDAO = new CertDAO(trans, hd, cid);

+		credDAO = new CredDAO(trans, hd, cid);

+		artiDAO = new ArtiDAO(trans, hd, cid);

+		

+		daos =(DAO<AuthzTrans, ?>[]) new DAO<?,?>[] {

+				hd,cid,certDAO,credDAO,artiDAO

+		};

+

+		// Setup Shutdown Hooks for Cluster and Pooled Sessions

+		Runtime.getRuntime().addShutdownHook(new Thread() {

+			@Override

+			public void run() {

+				for(DAO<AuthzTrans,?> dao : daos) {

+					dao.close(trans);

+				}

+

+//				sessionFilter.destroy();

+				cluster.close();

+			}

+		}); 

+	}

+	

+	public Result<CertResp> requestCert(AuthzTrans trans,Result<CertReq> req) {

+		if(req.isOK()) {

+			CA ca = trans.get(sCertAuth, null);

+			if(ca==null) {

+				return Result.err(Result.err(Result.ERR_BadData, "Invalid Cert Authority requested"));

+			}

+

+			// Allow only AAF CA without special permission

+			if(!ca.getName().equals("aaf") && !trans.fish( new AAFPermission(ca.getPermType(), ca.getName(), REQUEST))) {

+				return Result.err(Status.ERR_Denied, "'%s' does not have permission to request Certificates from Certificate Authority '%s'", 

+						trans.user(),ca.getName());

+			}

+

+			List<String> notes = null;

+			List<String> fqdns;

+			String email = null;

+

+			try {

+				Organization org = trans.org();

+				

+				// Policy 1: Requests are only by Pre-Authorized Configurations

+				ArtiDAO.Data add = null;

+				try {

+					for(InetAddress ia : InetAddress.getAllByName(trans.ip())) {

+						Result<List<ArtiDAO.Data>> ra = artiDAO.read(trans, req.value.mechid,ia.getHostName());

+						if(ra.isOKhasData()) {

+							add = ra.value.get(0);

+							break;

+						}

+					}

+				} catch (UnknownHostException e1) {

+					return Result.err(Result.ERR_BadData,"There is no host for %s",trans.ip());

+				}

+				

+				if(add==null) {

+					return Result.err(Result.ERR_BadData,"There is no configuration for %s",req.value.mechid);

+				}

+				

+				// Policy 2: If Config marked as Expired, do not create or renew

+				Date now = new Date();

+				if(add.expires!=null && now.after(add.expires)) {

+					return Result.err(Result.ERR_Policy,"Configuration for %s %s is expired %s",add.mechid,add.machine,Chrono.dateFmt.format(add.expires));

+				}

+				

+				// Policy 3: MechID must be current

+				Identity muser = org.getIdentity(trans, add.mechid);

+				if(muser == null) {

+					return Result.err(Result.ERR_Policy,"MechID must exist in %s",org.getName());

+				}

+				

+				// Policy 4: Sponsor must be current

+				Identity ouser = muser.owner();

+				if(ouser==null) {

+					return Result.err(Result.ERR_Policy,"%s does not have a current sponsor at %s",add.mechid,org.getName());

+				} else if(!ouser.isFound() || !ouser.isResponsible()) {

+					return Result.err(Result.ERR_Policy,"%s reports that %s cannot be responsible for %s",org.getName(),trans.user());

+				}

+				

+					// Set Email from most current Sponsor

+				email = ouser.email();

+				

+				// Policy 5: keep Artifact data current

+				if(!ouser.fullID().equals(add.sponsor)) {

+					add.sponsor = ouser.fullID();

+					artiDAO.update(trans, add);

+				}

+		

+				// Policy 6: Requester must be granted Change permission in Namespace requested

+				String mechNS = AAFCon.reverseDomain(req.value.mechid);

+				if(mechNS==null) {

+					return Result.err(Status.ERR_Denied, "%s does not reflect a valid AAF Namespace",req.value.mechid);

+				}

+				

+				// Policy 7: Caller must be the MechID or have specifically delegated permissions

+				if(!trans.user().equals(req.value.mechid) && !trans.fish(new AAFPermission(mechNS + ".certman", ca.getName() , "request"))) {

+					return Result.err(Status.ERR_Denied, "%s must have access to modify x509 certs in NS %s",trans.user(),mechNS);

+				}

+				

+	

+				// Policy 8: SANs only allowed by Exception... need permission

+				fqdns = new ArrayList<String>();

+				fqdns.add(add.machine);  // machine is first

+				if(req.value.fqdns.size()>1 && !trans.fish(new AAFPermission(ca.getPermType(), ca.getName(), SANS))) {

+					if(notes==null) {notes = new ArrayList<String>();}

+					notes.add("Warning: Subject Alternative Names only allowed by Permission: Get CSO Exception.  This Certificate will be created, but without SANs");

+				} else {

+					for(String m : req.value.fqdns) {

+						if(!add.machine.equals(m)) {

+							fqdns.add(m);

+						}

+					}

+				}

+				

+			} catch (Exception e) {

+				trans.error().log(e);

+				return Result.err(Status.ERR_Denied,"MechID Sponsorship cannot be determined at this time.  Try later");

+			}

+			

+			CSRMeta csrMeta;

+			try {

+				csrMeta = BCFactory.createCSRMeta(

+						ca, 

+						req.value.mechid, 

+						email, 

+						fqdns);

+				X509Certificate x509 = ca.sign(trans, csrMeta);

+				if(x509==null) {

+					return Result.err(Result.ERR_ActionNotCompleted,"x509 Certificate not signed by CA");

+				}

+				CertDAO.Data cdd = new CertDAO.Data();

+				cdd.ca=ca.getName();

+				cdd.serial=x509.getSerialNumber();

+				cdd.id=req.value.mechid;

+				cdd.x500=x509.getSubjectDN().getName();

+				cdd.x509=Factory.toString(trans, x509);

+				certDAO.create(trans, cdd);

+				

+				CredDAO.Data crdd = new CredDAO.Data();

+				crdd.other = Question.random.nextInt();

+				crdd.cred=getChallenge256SaltedHash(csrMeta.challenge(),crdd.other);

+				crdd.expires = x509.getNotAfter();

+				crdd.id = req.value.mechid;

+				crdd.ns = Question.domain2ns(crdd.id);

+				crdd.type = CredDAO.CERT_SHA256_RSA;

+				credDAO.create(trans, crdd);

+				

+				CertResp cr = new CertResp(trans,x509,csrMeta, compileNotes(notes));

+				return Result.ok(cr);

+			} catch (Exception e) {

+				trans.error().log(e);

+				return Result.err(Result.ERR_ActionNotCompleted,e.getMessage());

+			}

+		} else {

+			return Result.err(req);

+		}

+	}

+

+    public Result<CertResp> renewCert(AuthzTrans trans, Result<CertRenew> renew) {

+		if(renew.isOK()) {

+			return Result.err(Result.ERR_NotImplemented,"Not implemented yet");

+		} else {

+			return Result.err(renew);

+		}	

+	}

+

+	public Result<Void> dropCert(AuthzTrans trans, Result<CertDrop> drop) {

+		if(drop.isOK()) {

+			return Result.err(Result.ERR_NotImplemented,"Not implemented yet");

+		} else {

+			return Result.err(drop);

+		}	

+	}

+

+	///////////////

+	// Artifact

+	//////////////

+	public Result<Void> createArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {

+		Validator v = new Validator().artisRequired(list, 1);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+		for(ArtiDAO.Data add : list) {

+			try {

+				// Policy 1: MechID must exist in Org

+				Identity muser = trans.org().getIdentity(trans, add.mechid);

+				if(muser == null) {

+					return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());

+				}

+				

+				// Policy 2: MechID must have valid Organization Owner

+				Identity ouser = muser.owner();

+				if(ouser == null) {

+					return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",

+							trans.user(),add.mechid,trans.org().getName());

+				}

+				

+				// Policy 3: Calling ID must be MechID Owner

+				if(!trans.user().equals(ouser.fullID())) {

+					return Result.err(Result.ERR_Denied,"%s is not the Sponsor for %s at %s",

+							trans.user(),add.mechid,trans.org().getName());

+				}

+

+				// Policy 4: Renewal Days are between 10 and 60 (constants, may be parameterized)

+				if(add.renewDays<MIN_RENEWAL) {

+					add.renewDays = STD_RENEWAL;

+				} else if(add.renewDays>MAX_RENEWAL) {

+					add.renewDays = MAX_RENEWAL;

+				}

+				

+				// Policy 5: If Notify is blank, set to Owner's Email

+				if(add.notify==null || add.notify.length()==0) {

+					add.notify = "mailto:"+ouser.email();

+				}

+

+				// Set Sponsor from Golden Source

+				add.sponsor = ouser.fullID();

+				

+				

+			} catch (OrganizationException e) {

+				return Result.err(e);

+			}

+			// Add to DB

+			Result<ArtiDAO.Data> rv = artiDAO.create(trans, add);

+			// TODO come up with Partial Reporting Scheme, or allow only one at a time.

+			if(rv.notOK()) {

+				return Result.err(rv);

+			}

+		}

+		return Result.ok();

+	}

+

+	public Result<List<ArtiDAO.Data>> readArtifacts(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {

+		Validator v = new Validator().keys(add);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+		String ns = AAFCon.reverseDomain(add.mechid);

+		

+		if( trans.user().equals(add.mechid)

+			|| trans.fish(new AAFPermission(ns + ".access", "*", "read"))

+			|| (trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,add.mechid))==null) {

+				return artiDAO.read(trans, add);

+		} else {

+			return Result.err(Result.ERR_Denied,"%s is not %s, is not the sponsor, and doesn't have delegated permission.",trans.user(),add.mechid); // note: reason is set by 2nd case, if 1st case misses

+		}

+

+	}

+

+	public Result<List<ArtiDAO.Data>> readArtifactsByMechID(AuthzTrans trans, String mechid) throws OrganizationException {

+		Validator v = new Validator().nullOrBlank("mechid", mechid);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+		String ns = AAFCon.reverseDomain(mechid);

+		

+		String reason;

+		if(trans.fish(new AAFPermission(ns + ".access", "*", "read"))

+			|| (reason=trans.org().validate(trans,Organization.Policy.OWNS_MECHID,null,mechid))==null) {

+			return artiDAO.readByMechID(trans, mechid);

+		} else {

+			return Result.err(Result.ERR_Denied,reason); // note: reason is set by 2nd case, if 1st case misses

+		}

+

+	}

+

+	public Result<List<ArtiDAO.Data>> readArtifactsByMachine(AuthzTrans trans, String machine) {

+		Validator v = new Validator().nullOrBlank("machine", machine);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+		

+		// TODO do some checks?

+

+		Result<List<ArtiDAO.Data>> rv = artiDAO.readByMachine(trans, machine);

+		return rv;

+	}

+

+	public Result<Void> updateArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) throws OrganizationException {

+		Validator v = new Validator().artisRequired(list, 1);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+		

+		// Check if requesting User is Sponsor

+		//TODO - Shall we do one, or multiples?

+		for(ArtiDAO.Data add : list) {

+			// Policy 1: MechID must exist in Org

+			Identity muser = trans.org().getIdentity(trans, add.mechid);

+			if(muser == null) {

+				return Result.err(Result.ERR_Denied,"%s is not valid for %s", add.mechid,trans.org().getName());

+			}

+			

+			// Policy 2: MechID must have valid Organization Owner

+			Identity ouser = muser.owner();

+			if(ouser == null) {

+				return Result.err(Result.ERR_Denied,"%s is not a valid Sponsor for %s at %s",

+						trans.user(),add.mechid,trans.org().getName());

+			}

+

+			// Policy 3: Renewal Days are between 10 and 60 (constants, may be parameterized)

+			if(add.renewDays<MIN_RENEWAL) {

+				add.renewDays = STD_RENEWAL;

+			} else if(add.renewDays>MAX_RENEWAL) {

+				add.renewDays = MAX_RENEWAL;

+			}

+

+			// Policy 4: Data is always updated with the latest Sponsor

+			// Add to Sponsor, to make sure we are always up to date.

+			add.sponsor = ouser.fullID();

+

+			// Policy 5: If Notify is blank, set to Owner's Email

+			if(add.notify==null || add.notify.length()==0) {

+				add.notify = "mailto:"+ouser.email();

+			}

+

+			// Policy 4: only Owner may update info

+			if(trans.user().equals(add.sponsor)) {

+				return artiDAO.update(trans, add);

+			} else {

+				return Result.err(Result.ERR_Denied,"%s may not update info for %s",trans.user(),muser.fullID());

+			}

+			

+		}

+		return Result.err(Result.ERR_BadData,"No Artifacts to update");

+	}

+	

+	public Result<Void> deleteArtifact(AuthzTrans trans, String mechid, String machine) throws OrganizationException {

+		Validator v = new Validator()

+				.nullOrBlank("mechid", mechid)

+				.nullOrBlank("machine", machine);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+

+		Result<List<ArtiDAO.Data>> rlad = artiDAO.read(trans, mechid, machine);

+		if(rlad.notOKorIsEmpty()) {

+			return Result.err(Result.ERR_NotFound,"Artifact for %s %s does not exist.",mechid,machine);

+		}

+		

+		return deleteArtifact(trans,rlad.value.get(0));

+	}

+		

+	private Result<Void> deleteArtifact(AuthzTrans trans, ArtiDAO.Data add) throws OrganizationException {

+		// Policy 1: Record should be delete able only by Existing Sponsor.  

+		String sponsor=null;

+		Identity muser = trans.org().getIdentity(trans, add.mechid);

+		if(muser != null) {

+			Identity ouser = muser.owner();

+			if(ouser!=null) {

+				sponsor = ouser.fullID();

+			}

+		}

+		// Policy 1.a: If Sponsorship is deleted in system of Record, then 

+		// accept deletion by sponsor in Artifact Table

+		if(sponsor==null) {

+			sponsor = add.sponsor;

+		}

+		

+		String ns = AAFCon.reverseDomain(add.mechid);

+

+		if(trans.fish(new AAFPermission(ns + ".access", "*", "write"))

+				|| trans.user().equals(sponsor)) {

+			return artiDAO.delete(trans, add, false);

+		}

+		return null;

+	}

+

+	public Result<Void> deleteArtifact(AuthzTrans trans, List<ArtiDAO.Data> list) {

+		Validator v = new Validator().artisRequired(list, 1);

+		if(v.err()) {

+			return Result.err(Result.ERR_BadData,v.errs());

+		}

+

+		try {

+			boolean partial = false;

+			Result<Void> result=null;

+			for(ArtiDAO.Data add : list) {

+				result = deleteArtifact(trans, add);

+				if(result.notOK()) {

+					partial = true;

+				}

+			}

+			if(result == null) {

+				result = Result.err(Result.ERR_BadData,"No Artifacts to delete"); 

+			} else if(partial) {

+				result.partialContent(true);

+			}

+			return result;

+		} catch(Exception e) {

+			return Result.err(e);

+		}

+	}

+

+	private String[] compileNotes(List<String> notes) {

+		String[] rv;

+		if(notes==null) {

+			rv = NO_NOTES;

+		} else {

+			rv = new String[notes.size()];

+			notes.toArray(rv);

+		}

+		return rv;

+	}

+

+	private ByteBuffer getChallenge256SaltedHash(String challenge, int salt) throws NoSuchAlgorithmException {

+		ByteBuffer bb = ByteBuffer.allocate(Integer.SIZE + challenge.length());

+		bb.putInt(salt);

+		bb.put(challenge.getBytes());

+		byte[] hash = Hash.hashSHA256(bb.array());

+		return ByteBuffer.wrap(hash);

+	}

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CertManAPI.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CertManAPI.java
new file mode 100644
index 0000000..e802db2
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/CertManAPI.java
@@ -0,0 +1,285 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.service;

+

+import java.lang.reflect.Constructor;

+import java.util.ArrayList;

+import java.util.EnumSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Properties;

+import java.util.TreeMap;

+

+import org.onap.aaf.authz.cm.api.API_Artifact;

+import org.onap.aaf.authz.cm.api.API_Cert;

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.facade.Facade1_0;

+import org.onap.aaf.authz.cm.facade.FacadeFactory;

+import org.onap.aaf.authz.cm.mapper.Mapper.API;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.env.AuthzTransFilter;

+import org.onap.aaf.authz.server.AbsServer;

+import org.onap.aaf.cache.Cache;

+import org.onap.aaf.cache.Cache.Dated;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.api.DME2Exception;

+//import com.att.aft.dme2.api.DME2FilterHolder;

+//import com.att.aft.dme2.api.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.DME2Manager;

+import com.att.aft.dme2.api.DME2Server;

+import com.att.aft.dme2.api.DME2ServerProperties;

+import com.att.aft.dme2.api.DME2ServiceHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.util.DME2ServletHolder;

+import org.onap.aaf.cadi.Access;

+import org.onap.aaf.cadi.Access.Level;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.TrustChecker;

+import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;

+import org.onap.aaf.cadi.aaf.v2_0.AAFCon;

+import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;

+import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;

+import org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Trans;

+import org.onap.aaf.inno.env.util.Split;

+

+public class CertManAPI extends AbsServer {

+

+	private static final String USER_PERMS = "userPerms";

+	private static final Map<String,CA> certAuths = new TreeMap<String,CA>();

+	private static final String AAF_CERTMAN_CA_PREFIX = null;

+	public Facade1_0 facade1_0; // this is the default Facade

+	public Facade1_0 facade1_0_XML; // this is the XML Facade

+	public Map<String, Dated> cacheUser;

+	public AAFAuthn<?> aafAuthn;

+	public AAFLurPerm aafLurPerm;

+

+	private String[] EMPTY;

+	private AAFCon<?> aafcon;

+	

+	/**

+	 * Construct AuthzAPI with all the Context Supporting Routes that Authz needs

+	 * 

+	 * @param env

+	 * @param si 

+	 * @param dm 

+	 * @param decryptor 

+	 * @throws APIException 

+	 */

+	public CertManAPI(AuthzEnv env) throws Exception {

+		super(env,"CertMan");

+		env.setLog4JNames("log4j.properties","authz","cm","audit","init","trace");

+		

+		//aafcon = new AAFConHttp(env);

+		

+		aafLurPerm = aafcon.newLur();

+		// Note: If you need both Authn and Authz construct the following:

+		aafAuthn = aafcon.newAuthn(aafLurPerm);

+

+		String aaf_env = env.getProperty(Config.AAF_ENV);

+		if(aaf_env==null) {

+			throw new APIException("aaf_env needs to be set");

+		}

+		

+		// Initialize Facade for all uses

+		AuthzTrans trans = env.newTrans();

+		

+		// Load Supported Certificate Authorities by property 

+		for(String key : env.existingStaticSlotNames()) {

+			if(key.startsWith(AAF_CERTMAN_CA_PREFIX)) {

+				int idx = key.indexOf('.');

+				String[] params = Split.split(';', env.getProperty(key));

+				if(params.length>1) {

+					@SuppressWarnings("unchecked")

+					Class<CA> cac = (Class<CA>)Class.forName((String)params[0]);

+					Class<?> ptype[] = new Class<?>[params.length+1];

+					ptype[0]=Trans.class;

+					ptype[1]=String.class;

+					Object pinst[] = new Object[params.length+1];

+					pinst[0]=trans;

+					pinst[1]= key.substring(idx+1);

+					for(int i=1;i<params.length;++i) {

+						idx = i+1;

+						ptype[idx]=String.class;

+						pinst[idx]=params[i];

+					}

+					Constructor<CA> cons = cac.getConstructor(ptype);

+					CA ca = cons.newInstance(pinst);

+					certAuths.put(ca.getName(),ca);

+				}

+			}

+		}

+		if(certAuths.size()==0) {

+			throw new APIException("No Certificate Authorities have been configured in CertMan");

+		}

+		

+		CMService service = new CMService(trans, this);

+		// note: Service knows how to shutdown Cluster on Shutdown, etc.  See Constructor

+		facade1_0 = FacadeFactory.v1_0(this,trans, service,Data.TYPE.JSON);   // Default Facade

+		facade1_0_XML = FacadeFactory.v1_0(this,trans,service,Data.TYPE.XML); 

+		

+

+		synchronized(env) {

+			if(cacheUser == null) {

+				cacheUser = Cache.obtain(USER_PERMS);

+				Cache.startCleansing(env, USER_PERMS);

+				Cache.addShutdownHook(); // Setup Shutdown Hook to close cache

+			}

+		}

+		

+		////////////////////////////////////////////////////////////////////////////

+		// APIs

+		////////////////////////////////////////////////////////////////////////

+		API_Cert.init(this);

+		API_Artifact.init(this);

+		

+		StringBuilder sb = new StringBuilder();

+		trans.auditTrail(2, sb);

+		trans.init().log(sb);

+	}

+	

+	public CA getCA(String key) {

+		return certAuths.get(key);

+	}

+

+	public String[] getTrustChain(String key) {

+		CA ca = certAuths.get(key);

+		if(ca==null) {

+			return EMPTY;

+		} else {

+			return ca.getTrustChain();

+		}

+	}

+

+	/**

+	 * Setup XML and JSON implementations for each supported Version type

+	 * 

+	 * We do this by taking the Code passed in and creating clones of these with the appropriate Facades and properties

+	 * to do Versions and Content switches

+	 * 

+	 */

+	public void route(HttpMethods meth, String path, API api, Code code) throws Exception {

+		String version = "1.0";

+		// Get Correct API Class from Mapper

+		Class<?> respCls = facade1_0.mapper().getClass(api); 

+		if(respCls==null) throw new Exception("Unknown class associated with " + api.getClass().getName() + ' ' + api.name());

+		// setup Application API HTML ContentTypes for JSON and Route

+		String application = applicationJSON(respCls, version);

+		route(env,meth,path,code,application,"application/json;version="+version,"*/*");

+

+		// setup Application API HTML ContentTypes for XML and Route

+		application = applicationXML(respCls, version);

+		route(env,meth,path,code.clone(facade1_0_XML),application,"application/xml;version="+version);

+		

+		// Add other Supported APIs here as created

+	}

+	

+	public void routeAll(HttpMethods meth, String path, API api, Code code) throws Exception {

+		route(env,meth,path,code,""); // this will always match

+	}

+

+

+	/**

+	 * Start up AuthzAPI as DME2 Service

+	 * @param env

+	 * @param props

+	 * @throws DME2Exception

+	 * @throws CadiException 

+	 */

+	public void startDME2(Properties props) throws DME2Exception, CadiException {

+        DME2Manager dme2 = new DME2Manager("AAF Certman DME2Manager", props);

+

+

+        DME2ServiceHolder svcHolder;

+        List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();

+        svcHolder = new DME2ServiceHolder();

+        String serviceName = env.getProperty("DMEServiceName",null);

+    	if(serviceName!=null) {

+	    	svcHolder.setServiceURI(serviceName);

+	        svcHolder.setManager(dme2);

+	        svcHolder.setContext("/");

+	        

+	        

+	        

+	        DME2ServletHolder srvHolder = new DME2ServletHolder(this, new String[]{"/cert"});

+	        srvHolder.setContextPath("/*");

+	        slist.add(srvHolder);

+	        

+	        EnumSet<RequestDispatcherType> edlist = EnumSet.of(

+	        		RequestDispatcherType.REQUEST,

+	        		RequestDispatcherType.FORWARD,

+	        		RequestDispatcherType.ASYNC

+	        		);

+

+	        ///////////////////////

+	        // Apply Filters

+	        ///////////////////////

+	        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();

+	        

+	        // Secure all GUI interactions with AuthzTransFilter

+	        flist.add(new DME2FilterHolder(

+	        		new AuthzTransFilter(env,aafcon,TrustChecker.NOTRUST),

+	        		"/*", edlist));

+	        

+

+	        svcHolder.setFilters(flist);

+	        svcHolder.setServletHolders(slist);

+	        

+	        DME2Server dme2svr = dme2.getServer();

+	        DME2ServerProperties dsprops = dme2svr.getServerProperties();

+	        dsprops.setGracefulShutdownTimeMs(1000);

+	

+	        env.init().log("Starting AAF Certman Jetty/DME2 server...");

+	        dme2svr.start();

+	        try {

+//	        	if(env.getProperty("NO_REGISTER",null)!=null)

+	        	dme2.bindService(svcHolder);

+	        	env.init().log("DME2 is available as HTTP"+(dsprops.isSslEnable()?"/S":""),"on port:",dsprops.getPort());

+	            while(true) { // Per DME2 Examples...

+	            	Thread.sleep(5000);

+	            }

+	        } catch(InterruptedException e) {

+	            env.init().log("AAF Jetty Server interrupted!");

+	        } catch(Exception e) { // Error binding service doesn't seem to stop DME2 or Process

+	            env.init().log(e,"DME2 Initialization Error");

+	        	dme2svr.stop();

+	        	System.exit(1);

+	        }

+    	} else {

+    		env.init().log("Properties must contain DMEServiceName");

+    	}

+	}

+

+	public static void main(String[] args) {

+		setup(CertManAPI.class, "certman.props");

+

+	}

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/Code.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/Code.java
new file mode 100644
index 0000000..2e5e389
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/service/Code.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.service;

+

+import org.onap.aaf.authz.cm.facade.Facade1_0;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.cssa.rserv.HttpCode;

+

+public abstract class Code extends HttpCode<AuthzTrans,Facade1_0> implements Cloneable {

+

+	public Code(CertManAPI cma, String description, String ... roles) {

+		super(cma.facade1_0, description, roles);

+		// Note, the first "Code" will be created with default Facade, "JSON".

+		// use clone for another Code with XML

+	}

+	

+

+	public <D extends Code> D clone(Facade1_0 facade) throws Exception {

+		@SuppressWarnings("unchecked")

+		D d = (D)clone();

+		d.context = facade;

+		return d;

+	}

+

+}

diff --git a/authz-certman/src/main/java/org/onap/aaf/authz/cm/validation/Validator.java b/authz-certman/src/main/java/org/onap/aaf/authz/cm/validation/Validator.java
new file mode 100644
index 0000000..be9f728
--- /dev/null
+++ b/authz-certman/src/main/java/org/onap/aaf/authz/cm/validation/Validator.java
@@ -0,0 +1,165 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.validation;

+

+import java.util.List;

+

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO.Data;

+

+/**

+ * Validator

+ * Consistently apply content rules for content (incoming)

+ * 

+ * Note: We restrict content for usability in URLs (because RESTful service), and avoid 

+ * issues with Regular Expressions, and other enabling technologies. 

+ *

+ */

+public class Validator {

+	// Repeated Msg fragments

+	private static final String MECHID = "mechid";

+	private static final String MACHINE = "machine";

+	private static final String ARTIFACT_LIST_IS_NULL = "Artifact List is null.";

+	private static final String Y = "y.";

+	private static final String IES = "ies.";

+	private static final String ENTR = " entr";

+	private static final String MUST_HAVE_AT_LEAST = " must have at least ";

+	private static final String IS_NULL = " is null.";

+	private static final String ARTIFACTS_MUST_HAVE_AT_LEAST = "Artifacts must have at least ";

+	private StringBuilder msgs;

+

+	public Validator nullOrBlank(String name, String str) {

+		if(str==null) {

+			msg(name + IS_NULL);

+		} else if(str.length()==0) {

+			msg(name + " is blank.");

+		}

+		return this;

+	}

+	

+	private void msg(String ... strs) {

+		if(msgs==null) {

+			msgs=new StringBuilder();

+		}

+		for(String str : strs) {

+			msgs.append(str);

+		}

+		msgs.append('\n');

+	}

+	

+	public boolean err() {

+		return msgs!=null;

+	}

+	

+	public String errs() {

+		return msgs.toString();

+	}

+

+	public Validator notOK(Result<?> res) {

+		if(res==null) {

+			msgs.append("Result object is blank");

+		} else if(res.notOK()) {

+			msgs.append(res.getClass().getSimpleName() + " is not OK");

+		}

+		return this;

+	}

+

+	public Validator isNull(String name, Object obj) {

+		if(obj==null) {

+			msg(name + IS_NULL);

+		} 

+		return this;

+	}

+

+	public Validator nullBlankMin(String name, List<String> list, int min) {

+		if(list==null) {

+			msg(name + IS_NULL);

+		} else {

+			if(list.size()<min) {

+				msg(name + MUST_HAVE_AT_LEAST + min + ENTR + (min==1?Y:IES));

+			} else {

+				for(String s : list) {

+					nullOrBlank("List Item",s);

+				}

+			}

+		}

+		return this;

+	}

+

+	public Validator artisRequired(List<ArtiDAO.Data> list, int min) {

+		if(list==null) {

+			msg(ARTIFACT_LIST_IS_NULL);

+		} else {

+			if(list.size()<min) {

+				msg(ARTIFACTS_MUST_HAVE_AT_LEAST + min + ENTR + (min==1?Y:IES));

+			} else {

+				for(ArtiDAO.Data a : list) {

+					allRequired(a);

+				}

+			}

+		}

+		return this;

+	}

+

+	public Validator artisKeys(List<ArtiDAO.Data> list, int min) {

+		if(list==null) {

+			msg(ARTIFACT_LIST_IS_NULL);

+		} else {

+			if(list.size()<min) {

+				msg(ARTIFACTS_MUST_HAVE_AT_LEAST + min + ENTR + (min==1?Y:IES));

+			} else {

+				for(ArtiDAO.Data a : list) {

+					keys(a);

+				}

+			}

+		}

+		return this;

+	}

+

+

+	public Validator keys(ArtiDAO.Data add) {

+		if(add==null) {

+			msg("Artifact is null.");

+		} else {

+			nullOrBlank(MECHID, add.mechid);

+			nullOrBlank(MACHINE, add.machine);

+		}

+		return this;

+	}

+	

+	private Validator allRequired(Data a) {

+		if(a==null) {

+			msg("Artifact is null.");

+		} else {

+			nullOrBlank(MECHID, a.mechid);

+			nullOrBlank(MACHINE, a.machine);

+			nullOrBlank("ca",a.ca);

+			nullOrBlank("dir",a.dir);

+			nullOrBlank("os_user",a.os_user);

+			// Note: AppName, Notify & Sponsor are currently not required

+		}

+		return this;

+	}

+

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Artifact.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Artifact.java
new file mode 100644
index 0000000..96cba46
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Artifact.java
@@ -0,0 +1,108 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.api;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.mock;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.junit.BeforeClass;

+import org.junit.Rule;

+import org.junit.Test;

+import org.junit.rules.ExpectedException;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.api.API_Artifact;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.env.AuthzTrans;

+;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_API_Artifact {

+	

+	@Mock

+	private static API_Artifact api;

+	

+	@Mock

+	private static CertManAPI certManApi;

+	

+	private static CertManAPI noMockAPI;

+	private static API_Artifact api_1;

+	

+	private static HttpServletRequest req;

+	private static HttpServletResponse res;

+	

+	@BeforeClass

+	public static void setUp() {

+		AuthzTrans trans = mock(AuthzTrans.class);

+		req = mock(HttpServletRequest.class);

+		trans.setProperty("testTag", "UserValue");

+		trans.set(req);

+	}

+	

+	@Rule

+    public ExpectedException thrown= ExpectedException.none();

+	

+	@Test

+	public void init_bothValued() {

+		try {

+			api.init(certManApi);

+		} catch (Exception e) {

+			thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_Null_() {

+		try {

+			api.init(null);

+		} catch (Exception e) {

+			//thrown.expect(Exception.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_NMC_Null() {

+		try {

+			api_1.init(null);

+		} catch (Exception e) {

+			//thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_NMC() {

+		try {

+			api_1.init(noMockAPI);

+		} catch (Exception e) {

+			//thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Cert.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Cert.java
new file mode 100644
index 0000000..367e5e3
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/api/JU_API_Cert.java
@@ -0,0 +1,108 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.api;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.mock;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.junit.BeforeClass;

+import org.junit.Rule;

+import org.junit.Test;

+import org.junit.rules.ExpectedException;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.api.API_Cert;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.env.AuthzTrans;

+;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_API_Cert {

+	

+	@Mock

+	private static API_Cert api;

+	

+	@Mock

+	private static CertManAPI certManApi;

+	

+	private static CertManAPI noMockAPI;

+	private static API_Cert api_1;

+	

+	private static HttpServletRequest req;

+	private static HttpServletResponse res;

+	

+	@BeforeClass

+	public static void setUp() {

+		AuthzTrans trans = mock(AuthzTrans.class);

+		req = mock(HttpServletRequest.class);

+		trans.setProperty("testTag", "UserValue");

+		trans.set(req);

+	}

+	

+	@Rule

+    public ExpectedException thrown= ExpectedException.none();

+	

+	@Test

+	public void init_bothValued() {

+		try {

+			api.init(certManApi);

+		} catch (Exception e) {

+			//thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_Null_() {

+		try {

+			api.init(null);

+		} catch (Exception e) {

+			//thrown.expect(Exception.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_NMC_Null() {

+		try {

+			api_1.init(null);

+		} catch (Exception e) {

+			//thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void init_NMC() {

+		try {

+			api_1.init(noMockAPI);

+		} catch (Exception e) {

+			//thrown.expect(NullPointerException.class);

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_AppCA.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_AppCA.java
new file mode 100644
index 0000000..c6dd855
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_AppCA.java
@@ -0,0 +1,287 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.ca;

+

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+import java.math.BigInteger;

+import java.security.InvalidKeyException;

+import java.security.NoSuchAlgorithmException;

+import java.security.NoSuchProviderException;

+import java.security.Principal;

+import java.security.PublicKey;

+import java.security.SignatureException;

+import java.security.cert.CertificateEncodingException;

+import java.security.cert.CertificateException;

+import java.security.cert.CertificateExpiredException;

+import java.security.cert.CertificateNotYetValidException;

+import java.security.cert.X509Certificate;

+import java.util.Date;

+import java.util.Set;

+

+import javax.security.auth.x500.X500Principal;

+import javax.servlet.http.HttpServletRequest;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.InjectMocks;

+import org.mockito.Mock;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.ca.AppCA;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.dao.aaf.cached.CachedCertDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+

+import com.att.aft.dme2.api.http.HttpResponse;

+import com.att.aft.dme2.request.HttpRequest;

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.Trans;

+

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_AppCA {

+	

+	@Mock

+	private static CachedCertDAO certDAO;

+	

+	@Mock

+	private static HttpServletRequest req;

+	

+	@Mock

+	private static CSRMeta csrMeta;

+	

+	static Trans trans;

+	

+	static X509Certificate cert;

+	static byte [] name = {1,23,4,54,6,56};

+	

+	private static AppCA appCA;

+	

+	@BeforeClass

+	public static void setUp() throws CertificateException, CertException, IOException {

+		String str = "core java api";

+        byte[] b = str.getBytes();

+		Principal prc = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");

+		req = mock(HttpServletRequest.class);

+		appCA = mock(AppCA.class);

+		X509Certificate cert = new X509Certificate() {

+			

+			@Override

+			public boolean hasUnsupportedCriticalExtension() {

+				return false;

+			}

+			

+			@Override

+			public Set<String> getNonCriticalExtensionOIDs() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getExtensionValue(String oid) {

+				 

+				return null;

+			}

+			

+			@Override

+			public Set<String> getCriticalExtensionOIDs() {

+				 

+				return null;

+			}

+			

+			@Override

+			public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException,

+					InvalidKeyException, NoSuchProviderException, SignatureException {

+				 

+				

+			}

+			

+			@Override

+			public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,

+					NoSuchProviderException, SignatureException {

+				 

+				

+			}

+			

+			@Override

+			public String toString() {

+				 

+				return null;

+			}

+			

+			@Override

+			public PublicKey getPublicKey() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getEncoded() throws CertificateEncodingException {

+				 

+				return null;

+			}

+			

+			@Override

+			public int getVersion() {

+				 

+				return 0;

+			}

+			

+			@Override

+			public byte[] getTBSCertificate() throws CertificateEncodingException {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getSubjectUniqueID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Principal getSubjectDN() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getSignature() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getSigAlgParams() {

+				 

+				return null;

+			}

+			

+			@Override

+			public String getSigAlgOID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public String getSigAlgName() {

+				 

+				return null;

+			}

+			

+			@Override

+			public BigInteger getSerialNumber() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Date getNotBefore() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Date getNotAfter() {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getKeyUsage() {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getIssuerUniqueID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Principal getIssuerDN() {

+				 

+				return null;

+			}

+			

+			@Override

+			public int getBasicConstraints() {

+				 

+				return 0;

+			}

+			

+			@Override

+			public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {

+				 

+				

+			}

+			

+			@Override

+			public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {

+				

+			}

+		};

+		when(appCA.sign(Mockito.any(Trans.class), Mockito.any(CSRMeta.class))).thenReturn(cert);

+		certDAO = mock(CachedCertDAO.class, CALLS_REAL_METHODS);

+	}

+	

+	@Test

+	public void identity_True() throws CertificateException, IOException, CertException {

+		assertNotNull(appCA.sign(trans, csrMeta));

+	}

+	

+	

+	@Test

+	public void identityNull() throws CertificateException {

+		try {

+			assertNotNull(appCA.sign(null, csrMeta));

+		} catch (IOException e) {

+		

+			e.printStackTrace();

+		} catch (CertException e) {

+			

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void identityBothNull() throws CertificateException {

+		try {

+			assertNotNull(appCA.sign(null, null));

+		} catch (IOException e) {

+		

+			e.printStackTrace();

+		} catch (CertException e) {

+			

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_DevlCA.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_DevlCA.java
new file mode 100644
index 0000000..b859bf7
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/ca/JU_DevlCA.java
@@ -0,0 +1,287 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.ca;

+

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+import java.math.BigInteger;

+import java.security.InvalidKeyException;

+import java.security.NoSuchAlgorithmException;

+import java.security.NoSuchProviderException;

+import java.security.Principal;

+import java.security.PublicKey;

+import java.security.SignatureException;

+import java.security.cert.CertificateEncodingException;

+import java.security.cert.CertificateException;

+import java.security.cert.CertificateExpiredException;

+import java.security.cert.CertificateNotYetValidException;

+import java.security.cert.X509Certificate;

+import java.util.Date;

+import java.util.Set;

+

+import javax.security.auth.x500.X500Principal;

+import javax.servlet.http.HttpServletRequest;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.InjectMocks;

+import org.mockito.Mock;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.ca.DevlCA;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.dao.aaf.cached.CachedCertDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+

+import com.att.aft.dme2.api.http.HttpResponse;

+import com.att.aft.dme2.request.HttpRequest;

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.Trans;

+

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_DevlCA {

+	

+	@Mock

+	private static CachedCertDAO certDAO;

+	

+	@Mock

+	private static HttpServletRequest req;

+	

+	@Mock

+	private static CSRMeta csrMeta;

+	

+	static Trans trans;

+	

+	static X509Certificate cert;

+	static byte [] name = {1,23,4,54,6,56};

+	

+	private static DevlCA devICA;

+	

+	@BeforeClass

+	public static void setUp() throws CertificateException, CertException, IOException {

+		String str = "core java api";

+        byte[] b = str.getBytes();

+		Principal prc = new X500Principal("CN=Duke, OU=JavaSoft, O=Sun Microsystems, C=US");

+		req = mock(HttpServletRequest.class);

+		devICA = mock(DevlCA.class);

+		X509Certificate cert = new X509Certificate() {

+			

+			@Override

+			public boolean hasUnsupportedCriticalExtension() {

+				return false;

+			}

+			

+			@Override

+			public Set<String> getNonCriticalExtensionOIDs() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getExtensionValue(String oid) {

+				 

+				return null;

+			}

+			

+			@Override

+			public Set<String> getCriticalExtensionOIDs() {

+				 

+				return null;

+			}

+			

+			@Override

+			public void verify(PublicKey key, String sigProvider) throws CertificateException, NoSuchAlgorithmException,

+					InvalidKeyException, NoSuchProviderException, SignatureException {

+				 

+				

+			}

+			

+			@Override

+			public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, InvalidKeyException,

+					NoSuchProviderException, SignatureException {

+				 

+				

+			}

+			

+			@Override

+			public String toString() {

+				 

+				return null;

+			}

+			

+			@Override

+			public PublicKey getPublicKey() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getEncoded() throws CertificateEncodingException {

+				 

+				return null;

+			}

+			

+			@Override

+			public int getVersion() {

+				 

+				return 0;

+			}

+			

+			@Override

+			public byte[] getTBSCertificate() throws CertificateEncodingException {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getSubjectUniqueID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Principal getSubjectDN() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getSignature() {

+				 

+				return null;

+			}

+			

+			@Override

+			public byte[] getSigAlgParams() {

+				 

+				return null;

+			}

+			

+			@Override

+			public String getSigAlgOID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public String getSigAlgName() {

+				 

+				return null;

+			}

+			

+			@Override

+			public BigInteger getSerialNumber() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Date getNotBefore() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Date getNotAfter() {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getKeyUsage() {

+				 

+				return null;

+			}

+			

+			@Override

+			public boolean[] getIssuerUniqueID() {

+				 

+				return null;

+			}

+			

+			@Override

+			public Principal getIssuerDN() {

+				 

+				return null;

+			}

+			

+			@Override

+			public int getBasicConstraints() {

+				 

+				return 0;

+			}

+			

+			@Override

+			public void checkValidity(Date date) throws CertificateExpiredException, CertificateNotYetValidException {

+				 

+				

+			}

+			

+			@Override

+			public void checkValidity() throws CertificateExpiredException, CertificateNotYetValidException {

+				

+			}

+		};

+		when(devICA.sign(Mockito.any(Trans.class), Mockito.any(CSRMeta.class))).thenReturn(cert);

+		certDAO = mock(CachedCertDAO.class, CALLS_REAL_METHODS);

+	}

+	

+	@Test

+	public void identity_True() throws CertificateException, IOException, CertException {

+		assertNotNull(devICA.sign(trans, csrMeta));

+	}

+	

+	

+	@Test

+	public void identityNull() throws CertificateException {

+		try {

+			assertNotNull(devICA.sign(null, csrMeta));

+		} catch (IOException e) {

+		

+			e.printStackTrace();

+		} catch (CertException e) {

+			

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void identityBothNull() throws CertificateException {

+		try {

+			assertNotNull(devICA.sign(null, null));

+		} catch (IOException e) {

+		

+			e.printStackTrace();

+		} catch (CertException e) {

+			

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_BCFactory.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_BCFactory.java
new file mode 100644
index 0000000..3435d49
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_BCFactory.java
@@ -0,0 +1,132 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.cert;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+

+import java.io.File;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.security.Key;

+import java.security.PrivateKey;

+import java.security.PublicKey;

+

+import org.bouncycastle.operator.OperatorCreationException;

+import org.bouncycastle.pkcs.PKCS10CertificationRequest;

+import org.junit.BeforeClass;

+import org.junit.Rule;

+import org.junit.Test;

+import org.junit.rules.ExpectedException;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_BCFactory {

+	

+	private static BCFactory bcFactory = new BCFactory();

+	

+	private static BCFactory bcFact;

+	

+	private static PrivateKey pk;

+	

+	

+	private static Trans trans;

+	

+	

+	private static PKCS10CertificationRequest req;

+	

+	@BeforeClass

+	public static void setUp() throws IOException {

+		pk = new XYZKey();

+		trans = mock(Trans.class);

+		req = mock(PKCS10CertificationRequest.class);

+		when(req.getEncoded()).thenReturn(new byte[1]);

+		when(trans.start(Mockito.anyString(), Mockito.anyInt())).thenReturn(new TimeTaken(null, 0) {

+			

+			@Override

+			public void output(StringBuilder sb) {

+				// TODO Auto-generated method stub

+				

+			}

+		});

+		bcFact = mock(BCFactory.class);

+	}

+	

+	@Test

+	public void toStrin() throws OperatorCreationException, IOException, CertException {

+		assertNotNull(bcFactory.toString(trans, req));

+	}

+	

+	@Test

+	public void toStrinMoc() throws OperatorCreationException, IOException, CertException {

+		assertNotNull(bcFact.toString(trans, req));

+	}

+	

+	@Rule

+    public ExpectedException thrown= ExpectedException.none();

+	

+	@Test

+	public void toCSR()  {

+		try {

+			assertNotNull(bcFactory.toCSR(trans, new File("/random/path")));

+			thrown.expect(FileNotFoundException.class);

+		} catch (IOException e) {

+			

+			e.printStackTrace();

+		}

+	}

+	

+}

+

+class XYZKey implements Key, PublicKey, PrivateKey {

+	

+	int rotValue;

+	public XYZKey() {

+		rotValue = 1200213;

+	}

+	public String getAlgorithm() {

+		return "XYZ";

+	}

+

+	public String getFormat() {

+		return "XYZ Special Format";

+	}

+

+	public byte[] getEncoded() {

+		byte b[] = new byte[4];

+		b[3] = (byte) ((rotValue << 24) & 0xff);

+		b[2] = (byte) ((rotValue << 16) & 0xff);

+		b[1] = (byte) ((rotValue << 8) & 0xff);

+		b[0] = (byte) ((rotValue << 0) & 0xff);

+		return b;

+	}

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_CSRMeta.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_CSRMeta.java
new file mode 100644
index 0000000..da6b198
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/cert/JU_CSRMeta.java
@@ -0,0 +1,96 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.cert;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.mock;

+

+import java.io.IOException;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+

+import org.bouncycastle.asn1.x500.X500Name;

+import org.bouncycastle.operator.OperatorCreationException;

+import org.bouncycastle.pkcs.PKCS10CertificationRequest;

+import org.junit.BeforeClass;

+import org.junit.Rule;

+import org.junit.Test;

+import org.junit.rules.ExpectedException;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_CSRMeta {

+	

+	private static CSRMeta csrmeta;

+	private static Trans trans;

+	private static PKCS10CertificationRequest req;

+	

+	@BeforeClass

+	public static void setUp() {

+		trans = mock(Trans.class);

+		csrmeta = new CSRMeta();

+		csrmeta.cn("CN");

+		csrmeta.email("pupleti@ht.com");

+		csrmeta.mechID("HAKJH787");

+		csrmeta.o("O");

+		csrmeta.l("L");

+		csrmeta.st("ST");

+		csrmeta.c("C");

+		csrmeta.challenge("Challenge");

+		csrmeta.san("CA");

+	}

+	

+	@Test

+	public void x500Name() throws IOException {

+		

+		X500Name x500 = csrmeta.x500Name();

+		assertEquals(x500.toString(),"CN=CN,E=pupleti@ht.com,OU=HAKJH787,O=O,L=L,ST=ST,C=C");

+	}

+	

+	@Test

+	public void initialConversationCert() throws CertificateException, OperatorCreationException, IOException {

+		X509Certificate cert = csrmeta.initialConversationCert(trans);

+		assertEquals(cert.getBasicConstraints(),-1);

+	}

+	

+	@Test

+	public void generateCSR() throws IOException, CertException {

+		req = csrmeta.generateCSR(trans);

+		assertNotNull(req);

+	}

+	

+	@Rule

+    public ExpectedException thrown= ExpectedException.none();

+	

+	@Test

+	public void dump() throws IOException, CertException {

+		req = csrmeta.generateCSR(trans);

+		csrmeta.dump(req);

+	}

+	

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/data/JU_CertReq.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/data/JU_CertReq.java
new file mode 100644
index 0000000..3ff3088
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/data/JU_CertReq.java
@@ -0,0 +1,88 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.data;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+

+import java.io.IOException;

+import java.security.cert.X509Certificate;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.ca.CA;

+import org.onap.aaf.authz.cm.cert.BCFactory;

+import org.onap.aaf.authz.cm.cert.CSRMeta;

+import org.onap.aaf.authz.cm.cert.StandardFields;

+import org.onap.aaf.authz.cm.data.CertReq;

+

+import org.onap.aaf.cadi.cm.CertException;

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_CertReq {

+	

+	private static BCFactory bcFact;

+	

+	private static CSRMeta value;

+	

+	private static CertReq req;

+	

+	@BeforeClass

+	public static void setUp() {

+		bcFact = mock(BCFactory.class);

+		value = mock(CSRMeta.class);

+		req = mock(CertReq.class);

+		

+	}

+	

+	@Test

+	public void getCSRMeta() throws CertException {

+		//req = new CertReq();

+		req.mechid = "1213";

+		List<String> fqdnsas = new ArrayList<String>();

+		fqdnsas.add("String1");

+		List<String> emails = new ArrayList<String>();

+		emails.add("pupleti@hotmail.com");

+		req.emails = emails;

+		req.fqdns = fqdnsas;

+		StandardFields sf = mock(StandardFields.class);

+		req.certAuthority = new CA("testName", sf, "ALL") {

+			

+			@Override

+			public X509Certificate sign(Trans trans, CSRMeta csrmeta) throws IOException, CertException {

+	

+				return null;

+			}

+		};

+		req.sponsor = "asa@df.co";

+		assertNull(req.getCSRMeta());

+	}

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/facade/JU_FacadeImpl.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/facade/JU_FacadeImpl.java
new file mode 100644
index 0000000..2f305bb
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/facade/JU_FacadeImpl.java
@@ -0,0 +1,195 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.facade;

+

+import static org.junit.Assert.*;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+

+import java.io.IOException;

+

+import javax.servlet.ServletOutputStream;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+import javax.xml.namespace.QName;

+import javax.xml.validation.Schema;

+

+import org.junit.Before;

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.facade.FacadeImpl;

+import org.onap.aaf.authz.cm.mapper.Mapper;

+import org.onap.aaf.authz.cm.service.CMService;

+import org.onap.aaf.authz.cm.service.CertManAPI;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+

+import org.onap.aaf.cadi.aaf.AAFPermission;

+import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.LogTarget;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+import org.onap.aaf.rosetta.env.RosettaDF;

+import org.onap.aaf.rosetta.env.RosettaData;

+

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_FacadeImpl<REQ,CERT,ARTIFACTS,ERROR> {

+	

+	private static AuthzTrans trans;

+	private static HttpServletResponse resp;

+	private static CertManAPI certman;

+	private static FacadeImpl hImpl;

+	private static CMService service;

+	private Mapper<REQ,CERT,ARTIFACTS,ERROR> mapper;

+	private Data.TYPE dataType;

+	private static AuthzEnv env;

+	

+	private static FacadeImpl fImpl;

+	private static HttpServletRequest req;

+	

+	@Before

+	public void setUp() throws APIException, IOException {

+		fImpl = mock(FacadeImpl.class);

+		env = mock(AuthzEnv.class);

+		resp = mock(HttpServletResponse.class);

+		req = mock(HttpServletRequest.class);

+		hImpl = mock(FacadeImpl.class, CALLS_REAL_METHODS);

+		Result<Void> rvd = (Result) mock(Result.class);

+		trans = mock(AuthzTrans.class);

+		when(trans.error()).thenReturn(new LogTarget() {

+			

+			@Override

+			public void printf(String fmt, Object... vars) {}

+			

+			@Override

+			public void log(Throwable e, Object... msgs) {

+				e.getMessage();

+				e.printStackTrace();

+				msgs.toString();

+				

+			}

+			

+			@Override

+			public void log(Object... msgs) {

+			}

+			

+			@Override

+			public boolean isLoggable() {

+				

+				return false;

+			}

+		});

+		when(trans.start(Mockito.anyString(), Mockito.anyInt())).thenReturn(new TimeTaken("Now", 1) {

+			

+			@Override

+			public void output(StringBuilder sb) {

+				

+			}

+		});

+		when(fImpl.check(Mockito.any(AuthzTrans.class), Mockito.any(HttpServletResponse.class), Mockito.anyString())).thenReturn(rvd);

+		when(resp.getOutputStream()).thenReturn(new ServletOutputStream() {

+			

+			@Override

+			public void write(int b) throws IOException {

+				

+				

+			}

+		});

+		

+	}

+	

+	@Test

+	public void check() throws IOException {

+		AAFPermission ap = new AAFPermission("str1","str3","str2");

+		String perms = ap.getInstance();

+		assertNotNull(hImpl.check(trans, resp, perms));

+	}

+	

+	@Test

+	public void checkNull() throws IOException {

+		AAFPermission ap = new AAFPermission(null,"Str3","str2");

+		String perms = ap.getInstance();

+		assertNotNull(hImpl.check(trans, resp, perms));

+	}

+	

+	@Test

+	public void checkTwoNull() throws IOException {

+		AAFPermission ap = new AAFPermission(null,null,"str2");

+		String perms = ap.getInstance();

+		assertNotNull(fImpl.check(trans, resp, perms));

+	}

+	

+	@Test

+	public void checkAllNull() throws IOException {

+		AAFPermission ap = new AAFPermission(null,null,null);

+		String perms = ap.getInstance();

+		assertNotNull(fImpl.check(trans, resp, perms));

+	}

+	

+	@Test

+	public void checkTrans_null() throws IOException {

+		AAFPermission ap = new AAFPermission("str1","str3","str2");

+		String perms = ap.getInstance();

+		assertNotNull(hImpl.check(null, resp, perms));

+	}

+	

+	@Test

+	public void checkRespNull() throws IOException {

+		AAFPermission ap = new AAFPermission("str1","str3","str2");

+		String perms = ap.getInstance();

+		assertNotNull(hImpl.check(trans, null, perms));

+	}

+	

+	@Test

+	public void requestCert() {		

+		assertNotNull(hImpl.requestCert(trans, req, resp, true));

+	}

+	

+	@Test

+	public void renewCert() {		

+		assertNotNull(hImpl.renewCert(trans, req, resp, true));

+	}

+	

+	@Test

+	public void dropCert() {		

+		assertNotNull(hImpl.renewCert(trans, req, resp, true));

+	}

+	

+	@Test

+	public void createArtifacts() {		

+		assertNotNull(hImpl.createArtifacts(trans, req, resp));

+	}

+	

+	@Test

+	public void readArtifacts() {		

+		assertNotNull(hImpl.readArtifacts(trans, req, resp));

+	}

+}

diff --git a/authz-certman/src/test/java/org/onap/aaf/authz/cm/validation/JU_Validator.java b/authz-certman/src/test/java/org/onap/aaf/authz/cm/validation/JU_Validator.java
new file mode 100644
index 0000000..b760011
--- /dev/null
+++ b/authz-certman/src/test/java/org/onap/aaf/authz/cm/validation/JU_Validator.java
@@ -0,0 +1,100 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cm.validation;

+

+import static org.junit.Assert.*;

+

+import java.util.ArrayList;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cm.validation.Validator;

+import org.onap.aaf.dao.aaf.cass.ArtiDAO;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Validator {

+	

+	private static Validator validator;

+	

+	@BeforeClass

+	public static void setUp() {

+		validator = new Validator();

+	}

+	

+	@Test

+	public void nullCheck() {

+		assertNotNull(validator.nullOrBlank("TestName", null).errs());

+	}

+	

+	@Test

+	public void blankCheck() {

+		assertNotNull(validator.nullOrBlank("TestName", "").err());

+	}

+	

+	@Test

+	public void notOK_null() {

+		assertNotNull(validator.notOK(null));

+	}

+	

+	@Test

+	public void isNullCheck() {

+		assertNotNull(validator.isNull("TestName", null).errs());

+	}

+	

+	@Test

+	public void nullBlankMin() {

+		assertNotNull(validator.nullBlankMin("TestName", null, 0));

+	}

+	

+	@Test

+	public void artistsRequired() {

+		assertNotNull(validator.artisRequired(null, 0));

+	}

+	

+	@Test

+	public void artistRequired() {

+		assertNotNull(validator.artisRequired(new ArrayList<ArtiDAO.Data>(), -1));

+	}

+	

+	@Test

+	public void artistRequired_Null() {

+		assertNotNull(validator.artisRequired(null, -1));

+	}

+	

+	@Test

+	public void artistkeys() {

+		assertNotNull(validator.artisKeys(new ArrayList<ArtiDAO.Data>(), -1));

+	}

+	

+	@Test

+	public void artistKeys_Null() {

+		assertNotNull(validator.artisKeys(null, -1));

+	}

+	

+	@Test

+	public void keys() {

+		assertNotNull(validator.keys(new ArtiDAO.Data()));

+	}

+}

diff --git a/authz-client/pom.xml b/authz-client/pom.xml
index c1c3192..38fe15c 100644
--- a/authz-client/pom.xml
+++ b/authz-client/pom.xml
@@ -27,14 +27,12 @@
 	<modelVersion>4.0.0</modelVersion>

 

 	<!-- No Parent on Purpose!!! -->

-	

-	

-	<groupId>org.onap.aaf.authz</groupId>

 	<artifactId>authz-client</artifactId>

-	<version>1.0.0-SNAPSHOT</version>

-	<packaging>jar</packaging>

 	<name>Authz Client</name>

 	<description>Client and XSD Generated code for Authz</description>

+	<groupId>org.onap.aaf.authz</groupId>

+	<version>1.0.0-SNAPSHOT</version>

+	<packaging>jar</packaging>

 	<url>https://github.com/att/AAF</url>

 	<licenses>

 		<license>

@@ -51,7 +49,7 @@
 		</developer>

 	</developers>

 	

-	<properties>

+		<properties>

 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

 		<swm-distFiles-path>/opt/app/aft/${project.artifactId}/${project.version}</swm-distFiles-path>

 		<maven.test.failure.ignore>true</maven.test.failure.ignore>

@@ -180,7 +178,8 @@
 			</execution>

 		      </executions>

 		    </plugin>

-	 <plugin>

+			

+			 <plugin>

 				<groupId>org.sonatype.plugins</groupId>

 				<artifactId>nexus-staging-maven-plugin</artifactId>

 				<version>1.6.7</version>

@@ -238,6 +237,5 @@
 			<url>https://repository.jboss.org/nexus/content/groups/public</url>

 		</repository>

 	</repositories>

-

 </project>

 

diff --git a/authz-cmd/aafcli.sh b/authz-cmd/aafcli.sh
new file mode 100644
index 0000000..6eeddbb
--- /dev/null
+++ b/authz-cmd/aafcli.sh
@@ -0,0 +1,9 @@
+DIR=`pwd`
+DME2REG=$DIR/../dme2reg
+CLASSPATH=etc:target/authz-cmd-1.0.0-SNAPSHOT-jar-with-dependencies.jar
+
+java -cp $CLASSPATH \
+	-Dcadi_prop_files=../authz-service/src/main/sample/authAPI.props \
+	-DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG \
+	com.att.cmd.AAFcli $*
+
diff --git a/authz-cmd/etc/log4j.properties b/authz-cmd/etc/log4j.properties
new file mode 100644
index 0000000..fcd9da8
--- /dev/null
+++ b/authz-cmd/etc/log4j.properties
@@ -0,0 +1,54 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.SVR=org.apache.log4j.RollingFileAppender 

+log4j.appender.SVR.File=${user.home}/.aaf/authz-cmd.log

+log4j.appender.SVR.MaxFileSize=10000KB

+log4j.appender.SVR.MaxBackupIndex=1

+log4j.appender.SVR.layout=org.apache.log4j.PatternLayout 

+log4j.appender.SVR.layout.ConversionPattern=%d %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN,SVR

+

diff --git a/authz-cmd/pom.xml b/authz-cmd/pom.xml
new file mode 100644
index 0000000..e1a14e2
--- /dev/null
+++ b/authz-cmd/pom.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+    <artifactId>parent</artifactId>

+    <version>1.0.0-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+  

+  <artifactId>authz-cmd</artifactId>

+  <name>Authz Command</name>

+  <description>Command Line Processor 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>21</project.swmVersion>

+    	<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+  </properties>

+  

+  <dependencies>

+    <dependency>

+      <groupId>org.onap.aaf.cadi</groupId>

+      <artifactId>cadi-aaf</artifactId>

+    </dependency>

+    

+    <dependency>

+      <groupId>org.onap.aaf.authz</groupId>

+      <artifactId>authz-core</artifactId>

+    </dependency>

+    

+    <dependency> 

+      <groupId>jline</groupId> 

+      <artifactId>jline</artifactId> 

+      <version>2.14.2</version> 

+    </dependency>

+

+	<dependency>

+		<groupId>org.slf4j</groupId>

+		<artifactId>slf4j-log4j12</artifactId>

+	</dependency>

+

+  </dependencies>

+

+	<build>

+		<plugins>

+			<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>full</id>

+						<phase>package</phase>

+						<goals>

+							<goal>single</goal>

+						</goals>

+						<configuration>

+							<descriptors>

+								<descriptor>src/main/assemble/authz-cmd.xml</descriptor>

+							</descriptors>

+						</configuration>

+					</execution>

+				</executions>

+			</plugin>

+	

+				<plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<configuration>

+						<skip>true</skip>

+					</configuration>

+				</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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin> 

+		

+			</plugins>

+		<pluginManagement>

+			<plugins/>

+		</pluginManagement>

+	</build>

+<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+

+</project>

diff --git a/authz-cmd/src/main/assemble/authz-cmd.xml b/authz-cmd/src/main/assemble/authz-cmd.xml
new file mode 100644
index 0000000..c1f2ad6
--- /dev/null
+++ b/authz-cmd/src/main/assemble/authz-cmd.xml
@@ -0,0 +1,47 @@
+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

+  

+  <id>jar-with-dependencies</id>

+  <formats>

+    <format>jar</format>

+  </formats>

+

+  <includeBaseDirectory>false</includeBaseDirectory>

+  <dependencySets>

+    <dependencySet>

+      <unpack>true</unpack>

+      <scope>compile</scope>

+    </dependencySet>

+    

+  </dependencySets>

+  <fileSets>

+    <fileSet>

+      <directory>src/main/xsd</directory>

+    </fileSet>

+    <fileSet>

+      <directory>etc</directory>

+    </fileSet>

+   </fileSets>

+</assembly>

diff --git a/authz-cmd/src/main/assemble/swm.xml b/authz-cmd/src/main/assemble/swm.xml
new file mode 100644
index 0000000..f2e8683
--- /dev/null
+++ b/authz-cmd/src/main/assemble/swm.xml
@@ -0,0 +1,34 @@
+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<assembly>

+	<id>swm</id>

+	<formats>

+		<format>zip</format>

+	</formats>

+	<baseDirectory>${artifactId}</baseDirectory>

+	<fileSets>

+		<fileSet>

+			<directory>target/swm</directory>

+		</fileSet>

+	</fileSets>

+</assembly>

diff --git a/authz-cmd/src/main/config/log4j.properties b/authz-cmd/src/main/config/log4j.properties
new file mode 100644
index 0000000..fcd9da8
--- /dev/null
+++ b/authz-cmd/src/main/config/log4j.properties
@@ -0,0 +1,54 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.SVR=org.apache.log4j.RollingFileAppender 

+log4j.appender.SVR.File=${user.home}/.aaf/authz-cmd.log

+log4j.appender.SVR.MaxFileSize=10000KB

+log4j.appender.SVR.MaxBackupIndex=1

+log4j.appender.SVR.layout=org.apache.log4j.PatternLayout 

+log4j.appender.SVR.layout.ConversionPattern=%d %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN,SVR

+

diff --git a/authz-cmd/src/main/config/logging.props b/authz-cmd/src/main/config/logging.props
new file mode 100644
index 0000000..4d0f0f1
--- /dev/null
+++ b/authz-cmd/src/main/config/logging.props
@@ -0,0 +1,38 @@
+| ############################################################ 
+# Default Logging Configuration File 
+# 
+# You can use a different file by specifying a filename 
+# with the java.util.logging.config.file system property. 
+# For example java -Djava.util.logging.config.file=myfile 
+############################################################ 
+
+############################################################ 
+# Global properties 
+############################################################ 
+
+# "handlers" specifies a comma separated list of log Handler 
+# classes. These handlers will be installed during VM startup. 
+# Note that these classes must be on the system classpath. 
+# By default we only configure a ConsoleHandler, which will only 
+# show messages at the INFO and above levels. 
+handlers=java.util.logging.FileHandler 
+
+# Default global logging level. 
+# This specifies which kinds of events are logged across 
+# all loggers. For any given facility this global level 
+# can be overriden by a facility specific level 
+# Note that the ConsoleHandler also has a separate level 
+# setting to limit messages printed to the console. 
+.level=INFO 
+
+############################################################ 
+# Handler specific properties. 
+# Describes specific configuration info for Handlers. 
+############################################################ 
+java.util.logging.FileHandler.properties=autoFlush,fileName,dataPattern,name 
+java.util.logging.FileHandler.fileName=%h/.aaf/dme2.log 
+java.util.logging.FileHandlerFileHandler.autoFlush=true 
+java.util.logging.FileHandlerFileHandler.name=DailyRollingFileHandler 
+java.util.logging.FileHandlerFileHandler.datePattern='.'yyyy-MM-dd 
+com.att.aft.dme2.events.server.summary=WARN
+
diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/AAFcli.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/AAFcli.java
new file mode 100644
index 0000000..5e0c802
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/AAFcli.java
@@ -0,0 +1,722 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import java.io.BufferedReader;

+import java.io.Console;

+import java.io.File;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.InputStream;

+import java.io.InputStreamReader;

+import java.io.OutputStreamWriter;

+import java.io.PrintWriter;

+import java.io.Reader;

+import java.io.Writer;

+import java.net.HttpURLConnection;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Properties;

+

+import org.apache.log4j.PropertyConfigurator;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.cmd.mgmt.Mgmt;

+import org.onap.aaf.cmd.ns.NS;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+import org.onap.aaf.cmd.user.User;

+

+import com.att.aft.dme2.api.DME2Manager;

+import org.onap.aaf.cadi.Access.Level;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.Locator;

+import org.onap.aaf.cadi.SecuritySetter;

+import org.onap.aaf.cadi.client.PropertyLocator;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.cadi.config.SecurityInfo;

+import org.onap.aaf.cadi.config.SecurityInfoC;

+import org.onap.aaf.cadi.dme2.DME2Locator;

+import org.onap.aaf.cadi.filter.AccessGetter;

+import org.onap.aaf.cadi.http.HBasicAuthSS;

+import org.onap.aaf.cadi.http.HMangr;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.impl.Log4JLogTarget;

+import org.onap.aaf.inno.env.util.Split;

+

+import jline.console.ConsoleReader;

+

+public class AAFcli {

+

+	public static final String AAF_DEFAULT_REALM = "aaf_default_realm";

+	protected static PrintWriter pw;

+	protected HMangr hman;

+	// Storage for last reused client. We can do this

+	// because we're technically "single" threaded calls.

+	public Retryable<?> prevCall;

+

+	protected SecuritySetter<HttpURLConnection> ss;

+	protected AuthzEnv env;

+	private boolean close;

+	private List<Cmd> cmds;

+

+	// Lex State

+	private ArrayList<Integer> expect = new ArrayList<Integer>();

+	private boolean verbose = true;

+	private int delay;

+	private SecurityInfo si;

+	private boolean request = false;

+	private String force = null;

+	private boolean gui = false;

+

+	private static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF);

+	private static boolean isConsole = false;

+	private static boolean isTest = false;

+	private static boolean showDetails = false;

+	private static boolean ignoreDelay = false;

+	private static int globalDelay=0;

+	

+	public static int timeout() {

+		return TIMEOUT;

+	}

+

+	public AAFcli(AuthzEnv env, Writer wtr, HMangr hman, SecurityInfo si, SecuritySetter<HttpURLConnection> ss) throws APIException {

+		this.env = env;

+		this.ss = ss;

+		this.hman = hman;

+		this.si = si;

+		if (wtr instanceof PrintWriter) {

+			pw = (PrintWriter) wtr;

+			close = false;

+		} else {

+			pw = new PrintWriter(wtr);

+			close = true;

+		}

+

+

+		// client = new DRcli(new URI(aafurl), new

+		// BasicAuth(user,toPass(pass,true)))

+		// .apiVersion("2.0")

+		// .timeout(TIMEOUT);

+

+		/*

+		 * Create Cmd Tree

+		 */

+		cmds = new ArrayList<Cmd>();

+

+		Role role = new Role(this);

+		cmds.add(new Help(this, cmds));

+		cmds.add(new Version(this));

+		cmds.add(new Perm(role));

+		cmds.add(role);

+		cmds.add(new User(this));

+		cmds.add(new NS(this));

+		cmds.add(new Mgmt(this));

+	}

+

+	public void verbose(boolean v) {

+		verbose = v;

+	}

+

+	public void close() {

+		if (hman != null) {

+			hman.close();

+			hman = null;

+		}

+		if (close) {

+			pw.close();

+		}

+	}

+

+	public boolean eval(String line) throws Exception {

+		if (line.length() == 0) {

+			return true;

+		} else if (line.startsWith("#")) {

+			pw.println(line);

+			return true;

+		}

+

+		String[] largs = argEval(line);

+		int idx = 0;

+

+		// Variable replacement

+		StringBuilder sb = null;

+		while (idx < largs.length) {

+			int e = 0;

+			for (int v = largs[idx].indexOf("@["); v >= 0; v = largs[idx].indexOf("@[", v + 1)) {

+				if (sb == null) {

+					sb = new StringBuilder();

+				}

+				sb.append(largs[idx], e, v);

+				if ((e = largs[idx].indexOf(']', v)) >= 0) {

+					String p = env.getProperty(largs[idx].substring(v + 2, e++));

+					if (p != null) {

+						sb.append(p);

+					}

+				}

+			}

+			if (sb != null && sb.length() > 0) {

+				sb.append(largs[idx], e, largs[idx].length());

+				largs[idx] = sb.toString();

+				sb.setLength(0);

+			}

+			++idx;

+		}

+

+		idx = 0;

+		boolean rv = true;

+		while (rv && idx < largs.length) {

+			// Allow Script to change Credential

+			if (!gui) {

+				if("as".equalsIgnoreCase(largs[idx])) {

+					if (largs.length > ++idx) {

+						// get Password from Props with ID as Key

+						String user = largs[idx++];

+						int colon = user.indexOf(':');

+						String pass;

+						if (colon > 0) {

+							pass = user.substring(colon + 1);

+							user = user.substring(0, colon);

+						} else {

+							pass = env.getProperty(user);

+						}

+						

+						if (pass != null) {

+							pass = env.decrypt(pass, false);

+							env.setProperty(user, pass);

+							ss = new HBasicAuthSS(user, pass,(SecurityInfoC<HttpURLConnection>) si);

+							pw.println("as " + user);

+						} else { // get Pass from System Properties, under name of

+							// Tag

+							pw.println("ERROR: No password set for " + user);

+							rv = false;

+						}

+						continue;

+					}

+				} else if ("expect".equalsIgnoreCase(largs[idx])) {

+					expect.clear();

+					if (largs.length > idx++) {

+						if (!"nothing".equals(largs[idx])) {

+							for (String str : largs[idx].split(",")) {

+								try {

+									if ("Exception".equalsIgnoreCase(str)) {

+										expect.add(-1);

+									} else {

+										expect.add(Integer.parseInt(str));

+									}

+								} catch (NumberFormatException e) {

+									throw new CadiException("\"expect\" should be followed by Number");

+								}

+							}

+						++idx;

+						}

+					}

+					continue;

+					// Sleep, typically for reports, to allow DB to update

+					// Milliseconds

+					

+				} else if ("sleep".equalsIgnoreCase(largs[idx])) {

+					Integer t = Integer.parseInt(largs[++idx]);

+					pw.println("sleep " + t);

+					Thread.sleep(t);

+					++idx;

+					continue;

+				} else if ("delay".equalsIgnoreCase(largs[idx])) {

+					delay = Integer.parseInt(largs[++idx]);

+					pw.println("delay " + delay);

+					++idx;

+					continue;

+				} else if ("pause".equalsIgnoreCase(largs[idx])) {

+					pw.println("Press <Return> to continue...");

+					++idx;

+					new BufferedReader(new InputStreamReader(System.in)).readLine();

+					continue;

+				} else if ("exit".equalsIgnoreCase(largs[idx])) {

+					pw.println("Exiting...");

+					return false;

+				}

+

+			} 

+			

+			if("REQUEST".equalsIgnoreCase(largs[idx])) {

+				request=true;

+				++idx;

+			} else if("FORCE".equalsIgnoreCase(largs[idx])) {

+				force="true";

+				++idx;

+			} else if ("set".equalsIgnoreCase(largs[idx])) {

+				while (largs.length > ++idx) {

+					int equals = largs[idx].indexOf('=');

+					if (equals < 0) {

+						break;

+					}

+					String tag = largs[idx].substring(0, equals);

+					String value = largs[idx].substring(++equals);

+					pw.println("set " + tag + ' ' + value);

+					boolean isTrue = "TRUE".equalsIgnoreCase(value);

+					if("FORCE".equalsIgnoreCase(tag)) {

+						force = value;

+					} else if("REQUEST".equalsIgnoreCase(tag)) {

+						request = isTrue;

+					} else if("DETAILS".equalsIgnoreCase(tag)) {

+						showDetails = isTrue;

+					} else {

+						env.setProperty(tag, value);

+					}

+				}

+				continue;

+				// Allow Script to indicate if Failure is what is expected

+			}

+

+			int ret = 0;

+			for (Cmd c : cmds) {

+				if (largs[idx].equalsIgnoreCase(c.getName())) {

+					if (verbose) {

+						pw.println(line);

+						if (expect.size() > 0) {

+							pw.print("** Expect ");

+							boolean first = true;

+							for (Integer i : expect) {

+								if (first) {

+									first = false;

+								} else {

+									pw.print(',');

+								}

+								pw.print(i);

+							}

+							pw.println(" **");

+						}

+					}

+					try {

+						ret = c.exec(++idx, largs);

+						if (delay+globalDelay > 0) {

+							Thread.sleep(delay+globalDelay);

+						}

+					} catch (Exception e) {

+						if (expect.contains(-1)) {

+							pw.println(e.getMessage());

+							ret = -1;

+						} else {

+							throw e;

+						}

+					} finally {

+						clearSingleLineProperties();

+					}

+					rv = expect.isEmpty() ? true : expect.contains(ret);

+					if (verbose) {

+						if (rv) {

+							pw.println();

+						} else {

+							pw.print("!!! Unexpected Return Code: ");

+							pw.print(ret);

+							pw.println(", VALIDATE OUTPUT!!!");

+						}

+					}

+					return rv;

+				}

+			}

+			pw.write("Unknown Instruction \"");

+			pw.write(largs[idx]);

+			pw.write("\"\n");

+			idx = largs.length;// always end after one command

+		}

+		return rv;

+	}

+

+	private String[] argEval(String line) {

+		StringBuilder sb = new StringBuilder();

+		ArrayList<String> arr = new ArrayList<String>();

+		boolean start = true;

+		char quote = 0;

+		for (int i = 0; i < line.length(); ++i) {

+			char ch;

+			if (Character.isWhitespace(ch = line.charAt(i))) {

+				if (start) {

+					continue; // trim

+				} else if (quote != 0) {

+					sb.append(ch);

+				} else {

+					arr.add(sb.toString());

+					sb.setLength(0);

+					start = true;

+				}

+			} else if (ch == '\'' || ch == '"') { // toggle

+				if (quote == ch) {

+					quote = 0;

+				} else {

+					quote = ch;

+				}

+			} else {

+				start = false;

+				sb.append(ch);

+			}

+		}

+		if (sb.length() > 0) {

+			arr.add(sb.toString());

+		}

+

+		String[] rv = new String[arr.size()];

+		arr.toArray(rv);

+		return rv;

+	}

+

+	public static void keyboardHelp() {

+		System.out.println("'C-' means hold the ctrl key down while pressing the next key.");

+		System.out.println("'M-' means hold the alt key down while pressing the next key.");

+		System.out.println("For instance, C-b means hold ctrl key and press b, M-b means hold alt and press b\n");

+

+		System.out.println("Basic Keybindings:");

+		System.out.println("\tC-l - clear screen");        

+		System.out.println("\tC-a - beginning of line");

+		System.out.println("\tC-e - end of line");

+		System.out.println("\tC-b - backward character (left arrow also works)");

+		System.out.println("\tM-b - backward word");

+		System.out.println("\tC-f - forward character (right arrow also works)");

+		System.out.println("\tM-f - forward word");

+		System.out.println("\tC-d - delete character under cursor");

+		System.out.println("\tM-d - delete word forward");

+		System.out.println("\tM-backspace - delete word backward");

+		System.out.println("\tC-k - delete from cursor to end of line");

+		System.out.println("\tC-u - delete entire line, regardless of cursor position\n");

+

+		System.out.println("Command History:");

+		System.out.println("\tC-r - search backward in history (repeating C-r continues the search)");

+		System.out.println("\tC-p - move backwards through history (up arrow also works)");

+		System.out.println("\tC-n - move forwards through history (down arrow also works)\n");

+

+	}

+

+	/**

+	 * @param args

+	 */

+	public static void main(String[] args) {

+		int rv = 0;

+		// Cover for bash's need to escape *... (\\*)

+		for (int i = 0; i < args.length; ++i) {

+			if ("\\*".equals(args[i])) {

+				args[i] = "*";

+			}

+		}

+		

+		System.setProperty("java.util.logging.config.file", "etc/logging.props");

+		final AuthzEnv env = new AuthzEnv(System.getProperties());

+		

+		// Stop the (exceedingly annoying) DME2/other logs from printing console

+		InputStream is;

+

+		// Load Log4j too... sigh

+		is = ClassLoader.getSystemResourceAsStream("log4j.properties");

+		if(is==null) {

+			env.log(Level.WARN, "Cannot find 'log4j.properties' in Classpath.  Best option: add 'etc' directory to classpath");

+		} else {

+			try {

+				Properties props = new Properties();

+				props.load(is);

+				PropertyConfigurator.configure(props);

+			} catch (Exception e) {

+				e.printStackTrace();

+			} finally {

+				try {

+					is.close();

+				} catch (IOException e) {

+					env.debug().log(e); // only logging to avoid Sonar False positives.

+				}

+			}

+		}

+

+		env.loadFromSystemPropsStartsWith("AFT", "DME2", "aaf", "keyfile");

+		try {

+			Log4JLogTarget.setLog4JEnv("aaf", env);

+			GetProp gp = new GetProp(env);

+			String user = gp.get(false,Config.AAF_MECHID,"fully qualified id");

+			String pass = gp.get(true, Config.AAF_MECHPASS, "password is hidden");

+			if(env.getProperty(Config.AAF_URL)==null) {

+				String p = env.getProperty("DMEServiceName");

+				if(p!=null) {

+					boolean https = "true".equalsIgnoreCase(env.getProperty("AFT_DME2_SSL_ENABLE"));

+					env.setProperty(Config.AAF_URL, "http"+(https?"s":"")+"://DME2RESOLVE/"+p);

+				}

+			}

+			String aafUrl = gp.get(false, Config.AAF_URL, "https://DME2RESOLVE or Direct URL:port");

+

+			if(aafUrl!=null && aafUrl.contains("//DME2")) {

+				//gp.set(Config.AFT_LATITUDE,"Lookup from a Map App or table");

+				//gp.set(Config.AFT_LONGITUDE,"Lookup from a Map App or table");

+				//gp.set(Config.AFT_ENVIRONMENT,"Check DME2 Installations");

+			}

+

+			if (gp.err() != null) {

+				gp.err().append("to continue...");

+				System.err.println(gp.err());

+				System.exit(1);

+			}

+			

+

+			Reader rdr = null;

+			boolean exitOnFailure = true;

+			/*

+			 * Check for "-" options anywhere in command line

+			 */

+			StringBuilder sb = new StringBuilder();

+			for (int i = 0; i < args.length; ++i) {

+				if ("-i".equalsIgnoreCase(args[i])) {

+					rdr = new InputStreamReader(System.in);

+					// } else if("-o".equalsIgnoreCase(args[i])) {

+					// // shall we do something different? Output stream is

+					// already done...

+				} else if ("-f".equalsIgnoreCase(args[i])) {

+					if (args.length > i + 1) {

+						rdr = new FileReader(args[++i]);

+					}

+				} else if ("-a".equalsIgnoreCase(args[i])) {

+					exitOnFailure = false;

+				} else if ("-c".equalsIgnoreCase(args[i])) {

+					isConsole = true;

+				} else if ("-s".equalsIgnoreCase(args[i]) && args.length > i + 1) {

+					env.setProperty(Cmd.STARTDATE, args[++i]);

+				} else if ("-e".equalsIgnoreCase(args[i]) && args.length > i + 1) {

+					env.setProperty(Cmd.ENDDATE, args[++i]);

+				} else if ("-t".equalsIgnoreCase(args[i])) {

+					isTest = true;

+				} else if ("-d".equalsIgnoreCase(args[i])) {

+					showDetails = true;

+				} else if ("-n".equalsIgnoreCase(args[i])) {

+					ignoreDelay = true;

+				} else {

+					if (sb.length() > 0) {

+						sb.append(' ');

+					}

+					sb.append(args[i]);

+				}

+			}

+

+			SecurityInfo si = new SecurityInfo(env);

+			env.loadToSystemPropsStartsWith("AAF", "DME2");

+			Locator loc;

+			if(aafUrl.contains("//DME2RESOLVE")) {

+				DME2Manager dm = new DME2Manager("AAFcli DME2Manager", System.getProperties());

+				loc = new DME2Locator(env, dm, aafUrl);

+			} else {

+				loc = new PropertyLocator(aafUrl);

+			}

+

+			//Config.configPropFiles(new AccessGetter(env), env);

+			

+			TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF));

+			HMangr hman = new HMangr(env, loc).readTimeout(TIMEOUT).apiVersion("2.0");

+			

+			//TODO: Consider requiring a default in properties

+			env.setProperty(Config.AAF_DEFAULT_REALM, System.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));

+

+			AAFcli aafcli = new AAFcli(env, new OutputStreamWriter(System.out), hman, si, 

+				new HBasicAuthSS(user, env.decrypt(pass,false), (SecurityInfoC<HttpURLConnection>) si));

+			if(!ignoreDelay) {

+				File delay = new File("aafcli.delay");

+				if(delay.exists()) {

+					BufferedReader br = new BufferedReader(new FileReader(delay));

+					try {

+						globalDelay = Integer.parseInt(br.readLine());

+					} catch(Exception e) {

+						env.debug().log(e);

+					} finally {

+						br.close();

+					}

+				}

+			}

+			try {

+				if (isConsole) {

+					System.out.println("Type 'help' for short help or 'help -d' for detailed help with aafcli commands");

+					System.out.println("Type '?' for help with command line editing");

+					System.out.println("Type 'q', 'quit', or 'exit' to quit aafcli\n");

+

+					ConsoleReader reader = new ConsoleReader();

+					try {

+						reader.setPrompt("aafcli > ");

+	

+						String line;

+						while ((line = reader.readLine()) != null) {

+							showDetails = (line.contains("-d"))?true:false;

+	

+							if (line.equalsIgnoreCase("quit") || line.equalsIgnoreCase("q") || line.equalsIgnoreCase("exit")) {

+								break;

+							} else if (line.equalsIgnoreCase("--help -d") || line.equalsIgnoreCase("help -d") 

+									|| line.equalsIgnoreCase("help")) {

+								line = "--help";

+							} else if (line.equalsIgnoreCase("cls")) {

+								reader.clearScreen();

+								continue;

+							} else if (line.equalsIgnoreCase("?")) {

+								keyboardHelp();

+								continue;

+							}

+							try {

+								aafcli.eval(line);

+								pw.flush();

+							} catch (Exception e) {

+								pw.println(e.getMessage());

+								pw.flush();

+							}

+						}

+					} finally {

+						reader.close();

+					}

+				} else if (rdr != null) {

+					BufferedReader br = new BufferedReader(rdr);

+					String line;

+					while ((line = br.readLine()) != null) {

+						if (!aafcli.eval(line) && exitOnFailure) {

+							rv = 1;

+							break;

+						}

+					}

+				} else { // just run the command line

+					aafcli.verbose(false);

+					if (sb.length() == 0) {

+						sb.append("--help");

+					}

+					rv = aafcli.eval(sb.toString()) ? 0 : 1;

+				}

+			} finally {

+				aafcli.close();

+

+				// Don't close if No Reader, or it's a Reader of Standard In

+				if (rdr != null && !(rdr instanceof InputStreamReader)) {

+					rdr.close();

+				}

+			}

+		} catch (MessageException e) {

+			System.out.println("MessageException caught");

+

+			System.err.println(e.getMessage());

+		} catch (Exception e) {

+			e.printStackTrace(System.err);

+		}

+		System.exit(rv);

+

+	}

+

+	private static class GetProp {

+		private Console cons = System.console();

+		private StringBuilder err = null;

+		private AuthzEnv env;

+		

+		public GetProp(AuthzEnv env) {

+			this.env = env;

+		}

+

+		public String get(final boolean pass, final String tag, final String other)  {

+			String data = env.getProperty(tag,null);

+			if (data == null) {

+				if(cons!=null) {

+					if(pass) {

+						char[] cp = System.console().readPassword("%s: ",tag);

+						if(cp!=null) {

+							data=String.valueOf(cp);

+						}

+					} else {

+						cons.writer().format("%s: ", tag);

+						cons.flush();

+						data = cons.readLine();

+					}

+				}

+				if(data==null) {

+					if(err == null) {

+						err  = new StringBuilder("Add -D");

+					} else {

+						err.append(", -D");

+					}

+					err.append(tag);

+					if(other!=null) {

+						err.append("=<");

+						err.append(other);

+						err.append('>');

+					}

+				}

+			}

+			return data;

+		}

+		

+		public void set(final String tag, final String other)  {

+			String data = env.getProperty(tag,null);

+			if (data == null) {

+				if(cons!=null) {

+					cons.writer().format("%s: ", tag);

+					cons.flush();

+					data = cons.readLine();

+				}

+				if(data==null) {

+					if(err == null) {

+						err  = new StringBuilder("Add -D");

+					} else {

+						err.append(", -D");

+					}

+					err.append(tag);

+					if(other!=null) {

+						err.append("=<");

+						err.append(other);

+						err.append('>');

+					}

+				}

+			}

+			if(data!=null) {

+				System.setProperty(tag, data);

+			}

+		}

+

+		public StringBuilder err() {

+			return err;

+		}

+	}

+

+	public boolean isTest() {

+		return AAFcli.isTest;

+	}

+	

+	public boolean isDetailed() {

+		return AAFcli.showDetails;

+	}

+

+	public String typeString(Class<?> cls, boolean json) {

+		return "application/" + cls.getSimpleName() + "+" + (json ? "json" : "xml") + ";version=" + hman.apiVersion();

+	}

+

+	public String forceString() {

+		return force;

+	}

+

+	public boolean addRequest() {

+		return request;

+	}

+

+	public void clearSingleLineProperties() {

+		force  = null;

+		request = false;

+		showDetails = false;

+	}

+

+	public void gui(boolean b) {

+		gui  = b;

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/BaseCmd.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/BaseCmd.java
new file mode 100644
index 0000000..ff01b01
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/BaseCmd.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import java.util.ArrayList;

+import java.util.List;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+

+public class BaseCmd<CMD extends Cmd> extends Cmd  {

+	protected List<Cmd> 	cmds;

+

+	public BaseCmd(AAFcli aafcli, String name, Param ... params) {

+		super(aafcli, null, name, params);

+		cmds = new ArrayList<Cmd>();

+	}

+	

+	public BaseCmd(CMD parent, String name, Param ... params) {

+		super(parent.aafcli, parent, name, params);

+		cmds = new ArrayList<Cmd>();

+	}

+

+	

+	@Override

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		if(args.length-idx<1) {

+			pw().println(build(new StringBuilder(),null).toString());

+		} else {

+			String s = args[idx];

+			String name;

+			Cmd empty = null;

+			for(Cmd c: cmds) {

+				name = c.getName();

+				if(name==null && empty==null) { // Mark with Command is null, and take the first one.  

+					empty = c;

+				} else if(s.equalsIgnoreCase(c.getName()))

+					return c.exec(idx+1, args);

+			}

+			if(empty!=null) {

+				return empty.exec(idx, args); // If name is null, don't account for it on command line.  jg 4-29

+			}

+			pw().println("Instructions not understood.");

+		}

+		return 0;

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/BasicAuth.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/BasicAuth.java
new file mode 100644
index 0000000..3e1f1fb
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/BasicAuth.java
@@ -0,0 +1,56 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import java.io.IOException;

+

+import com.att.aft.dme2.api.DME2Client;

+import org.onap.aaf.cadi.SecuritySetter;

+import org.onap.aaf.cadi.Symm;

+

+public class BasicAuth implements SecuritySetter<DME2Client> {

+	private String cred;

+	private String user;

+	

+	public BasicAuth(String user, String pass) throws IOException {

+		this.user = user;

+		cred = "Basic " + Symm.base64.encode(user+':'+pass);

+	}

+	

+	@Override

+	public void setSecurity(DME2Client client) {

+		client.addHeader("Authorization" , cred);

+	}

+

+	@Override

+	public String getID() {

+		return user;

+	}

+

+	//@Override

+	public int setLastResponse(int respCode) {

+		// TODO Auto-generated method stub

+		return 0;

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/Cmd.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/Cmd.java
new file mode 100644
index 0000000..3c7f4ac
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/Cmd.java
@@ -0,0 +1,499 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import java.io.PrintWriter;

+import java.io.StringReader;

+import java.sql.Date;

+import java.text.DateFormat;

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Comparator;

+import java.util.GregorianCalendar;

+import java.util.List;

+import java.util.Stack;

+import java.util.concurrent.ConcurrentHashMap;

+

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.http.HMangr;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data.TYPE;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.util.Chrono;

+import org.onap.aaf.rosetta.env.RosettaDF;

+import org.onap.aaf.rosetta.env.RosettaEnv;

+

+import aaf.v2_0.Error;

+import aaf.v2_0.History;

+import aaf.v2_0.History.Item;

+import aaf.v2_0.Request;

+

+

+public abstract class Cmd {

+	private static final String AAF_DEFAULT_REALM = "aaf_default_realm";

+	

+	private static final DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");

+	protected static final String BLANK = "";

+	protected static final String COMMA = ","; // for use in splits

+

+	protected static final int lineLength = 80;

+

+	private final static String hformat = "%-23s %-5s %-20s %-35s\n";

+

+	public static final String STARTDATE = "startdate";

+	public static final String ENDDATE = "enddate";

+	

+	private String name;

+	private final Param[] params;

+	private int required;

+	protected final Cmd parent;

+	protected final List<Cmd> children;

+	private final ConcurrentHashMap<Class<?>,RosettaDF<?>> dfs = new ConcurrentHashMap<Class<?>,RosettaDF<?>>();

+	public final AAFcli aafcli;

+	protected Env env;

+

+	public Cmd(AAFcli aafcli, String name, Param ... params) {

+		this(aafcli,null, name,params);

+	}

+

+	public Cmd(Cmd parent, String name, Param ... params) {

+		this(parent.aafcli,parent, name,params);

+	}

+

+	Cmd(AAFcli aafcli, Cmd parent, String name, Param ... params) {

+		this.parent = parent;

+		this.aafcli = aafcli;

+		this.env = aafcli.env;

+		if(parent!=null) {

+			parent.children.add(this);

+		}

+		children = new ArrayList<Cmd>();

+		this.params = params;

+		this.name = name;

+		required=0;

+		for(Param p : params) {

+			if(p.required) {

+				++required;

+			}

+		}

+	}

+	

+	public final int exec(int idx, String ... args) throws CadiException, APIException, LocatorException {

+		if(args.length-idx<required) {

+			throw new CadiException(build(new StringBuilder("Too few args: "),null).toString());

+		}

+		return _exec(idx,args);

+	}

+	

+	protected abstract int _exec(int idx, final String ... args) throws CadiException, APIException, LocatorException;

+	

+	public void detailedHelp(int indent,StringBuilder sb) {

+	}

+

+	protected void detailLine(StringBuilder sb, int length, String s) {

+		multiChar(sb,length,' ',0);

+		sb.append(s);

+	}

+

+	public void apis(int indent,StringBuilder sb) {

+	}

+

+	protected void api(StringBuilder sb, int _indent, HttpMethods hmeth, String pathInfo, Class<?> cls,boolean head) {

+	    int indent = _indent;

+	    final String meth = hmeth.name();

+		if(head) {

+			sb.append('\n');

+			detailLine(sb,indent,"APIs:");

+		}

+		indent+=2;

+		multiChar(sb,indent,' ',0);

+		sb.append(meth);

+		sb.append(' ');

+		sb.append(pathInfo);

+		String cliString = aafcli.typeString(cls,true);

+		if(indent+meth.length()+pathInfo.length()+cliString.length()+2>80) {

+			sb.append(" ...");

+			multiChar(sb,indent+3+meth.length(),' ',0);

+		} else { // same line

+			sb.append(' ');

+		}

+		sb.append(cliString);

+	}

+

+	protected void multiChar(StringBuilder sb, int length, char c, int indent) {

+		sb.append('\n');

+		for(int i=0;i<indent;++i)sb.append(' ');

+		for(int i=indent;i<length;++i)sb.append(c);

+	}

+

+	public StringBuilder build(StringBuilder sb, StringBuilder detail) {

+		if(name!=null) {

+			sb.append(name);

+			sb.append(' ');

+		}

+		int line = sb.lastIndexOf("\n")+1;

+		if(line<0) {

+			line=0;

+		}

+		int indent = sb.length()-line;

+		for(Param p : params) {

+			sb.append(p.required?'<':'[');

+			sb.append(p.tag);

+			sb.append(p.required?"> ": "] ");

+		}

+		

+		boolean first = true;

+		for(Cmd child : children) {

+			if(first) {

+				first = false;

+			} else if(detail==null) {

+				multiChar(sb,indent,' ',0);

+			} else {

+				// Write parents for Detailed Report

+				Stack<String> stack = new Stack<String>();

+				for(Cmd c = child.parent;c!=null;c=c.parent) {

+					if(c.name!=null) {

+						stack.push(c.name);

+					}

+				}

+				if(!stack.isEmpty()) {

+					sb.append("  ");

+					while(!stack.isEmpty()) {

+						sb.append(stack.pop());

+						sb.append(' ');

+					}

+				}

+			}

+			child.build(sb,detail);

+			if(detail!=null) {

+				child.detailedHelp(4, detail);

+				// If Child wrote something, then add, bracketing by lines

+				if(detail.length()>0) {

+					multiChar(sb,80,'-',2);

+					sb.append(detail);

+					sb.append('\n');

+					multiChar(sb,80,'-',2);

+					sb.append('\n');

+					detail.setLength(0); // reuse

+				} else {

+					sb.append('\n');

+				}

+			}

+		}

+		return sb;

+	}

+	

+	protected void error(Future<?> future) {

+		StringBuilder sb = new StringBuilder("Failed");

+		String desc = future.body();

+		int code = future.code();

+		if(desc==null || desc.length()==0) {

+			withCode(sb,code);

+		} else if(desc.startsWith("{")) {

+			StringReader sr = new StringReader(desc);

+			try {

+				// Note: 11-18-2013.  This rather convoluted Message Structure required by TSS Restful Specs, reflecting "Northbound" practices.

+				Error err = getDF(Error.class).newData().in(TYPE.JSON).load(sr).asObject();

+				sb.append(" [");

+				sb.append(err.getMessageId());

+				sb.append("]: ");

+				String messageBody = err.getText();

+				List<String> vars = err.getVariables();

+				int pipe;

+				for (int varCounter=0;varCounter<vars.size();) {

+					String var = vars.get(varCounter);

+					++varCounter;

+					if (messageBody.indexOf("%" + varCounter) >= 0) {

+						if((pipe = var.indexOf('|'))>=0) {  // In AAF, we use a PIPE for Choice

+							if (aafcli.isTest()) {

+								String expiresStr = var.substring(pipe);

+								var = var.replace(expiresStr, "[Placeholder]");

+							} else {

+								StringBuilder varsb = new StringBuilder(var);

+								varsb.deleteCharAt(pipe);

+								var = varsb.toString();

+							}

+							messageBody = messageBody.replace("%" + varCounter, varCounter-1 + ") " + var);

+						} else {

+							messageBody = messageBody.replace("%" + varCounter, var);

+						}

+					}

+				}

+				sb.append(messageBody);

+			} catch (Exception e) {

+				withCode(sb,code);

+				sb.append(" (Note: Details cannot be obtained from Error Structure)");

+			}

+		} else if(desc.startsWith("<html>")){ // Core Jetty, etc sends HTML for Browsers

+			withCode(sb,code);

+		} else {

+			sb.append(" with code ");

+			sb.append(code);

+			sb.append(", ");

+			sb.append(desc);

+		}

+		pw().println(sb);

+	}

+

+	

+	private void withCode(StringBuilder sb, Integer code) {

+		sb.append(" with code ");

+		sb.append(code);

+		switch(code) {

+			case 401:

+				sb.append(" (HTTP Not Authenticated)");

+				break;

+			case 403:

+				sb.append(" (HTTP Forbidden)");

+				break;

+			case 404:

+				sb.append(" (HTTP Not Found)");

+				break;

+			default:

+		}

+	}

+

+	/**

+	 * Consistently set start and end dates from Requests (all derived from Request)

+	 * @param req

+	 */

+	protected void setStartEnd(Request req) {

+		// Set Start/End Dates, if exist

+		String str;

+		if((str = env.getProperty(Cmd.STARTDATE,null))!=null) {

+			req.setStart(Chrono.timeStamp(Date.valueOf(str)));

+		}

+		

+		if((str = env.getProperty(Cmd.ENDDATE,null))!=null) {

+			req.setEnd(Chrono.timeStamp(Date.valueOf(str)));

+		}

+	}

+

+	@SuppressWarnings("unchecked")

+	protected<T> RosettaDF<T> getDF(Class<T> cls) throws APIException {

+		RosettaDF<T> rdf = (RosettaDF<T>)dfs.get(cls);

+		if(rdf == null) {

+			rdf = env().newDataFactory(cls);

+			dfs.put(cls, rdf);

+		}

+		return rdf;

+	}

+

+	public void activity(History history, String header) {

+		if (history.getItem().isEmpty()) {

+			int start = header.indexOf('[');

+			if (start >= 0) {

+				pw().println("No Activity Found for " + header.substring(start));

+			}

+		} else {

+			pw().println(header);

+			for(int i=0;i<lineLength;++i)pw().print('-');

+			pw().println();

+								

+			pw().format(hformat,"Date","Table","User","Memo");

+			for(int i=0;i<lineLength;++i)pw().print('-');

+			pw().println();

+	

+			// Save Server time by Sorting locally

+			List<Item> items = history.getItem();

+			java.util.Collections.sort(items, new Comparator<Item>() {

+				@Override

+				public int compare(Item o1, Item o2) {

+					return o2.getTimestamp().compare(o1.getTimestamp());

+				}

+			});

+			

+			for(History.Item item : items) {

+				GregorianCalendar gc = item.getTimestamp().toGregorianCalendar();

+				pw().format(hformat,

+					dateFmt.format(gc.getTime()),

+					item.getTarget(),

+					item.getUser(),

+					item.getMemo());

+			}

+		}

+	}

+	

+	/**

+	 * Turn String Array into a | delimited String

+	 * @param options

+	 * @return

+	 */

+	public static String optionsToString(String[] options) {

+		StringBuilder sb = new StringBuilder();

+		boolean first = true;

+		for(String s : options) {

+			if(first) {

+				first = false;

+			} else {

+				sb.append('|');

+			}

+			sb.append(s);

+		}

+		return sb.toString();

+	}

+	

+	/**

+	 * return which index number the Option matches.

+	 * 

+	 * throws an Exception if not part of this Option Set

+	 * 

+	 * @param options

+	 * @param test

+	 * @return

+	 * @throws Exception

+	 */

+	public int whichOption(String[] options, String test) throws CadiException {

+		for(int i=0;i<options.length;++i) {

+			if(options[i].equals(test)) {

+				return i;

+			}

+		}

+		throw new CadiException(build(new StringBuilder("Invalid Option: "),null).toString());

+	}

+

+	protected RosettaEnv env() {

+		return aafcli.env;

+	}

+

+	protected HMangr hman() {

+		return aafcli.hman;

+	}

+

+	public<RET> RET same(Retryable<RET> retryable) throws APIException, CadiException, LocatorException {

+		// We're storing in AAFCli, because we know it's always the same, and single threaded

+		if(aafcli.prevCall!=null) {

+			retryable.item(aafcli.prevCall.item());

+			retryable.lastClient=aafcli.prevCall.lastClient;

+		}

+		

+		RET ret = aafcli.hman.same(aafcli.ss,retryable);

+		

+		// Store last call in AAFcli, because Cmds are all different instances.

+		aafcli.prevCall = retryable;

+		return ret;

+	}

+

+	public<RET> RET all(Retryable<RET> retryable) throws APIException, CadiException, LocatorException {

+		this.setQueryParamsOn(retryable.lastClient);

+		return aafcli.hman.all(aafcli.ss,retryable);

+	}

+

+	public<RET> RET oneOf(Retryable<RET> retryable,String host) throws APIException, CadiException, LocatorException {

+		this.setQueryParamsOn(retryable.lastClient);

+		return aafcli.hman.oneOf(aafcli.ss,retryable,true,host);

+	}

+

+	protected PrintWriter pw() {

+		return AAFcli.pw;

+	}

+

+	public String getName() {

+		return name;

+	}

+	

+	public void reportHead(String ... str) {

+		pw().println();

+		boolean first = true;

+		int i=0;

+		for(String s : str) {

+			if(first) {

+				if(++i>1) {

+					first = false;

+					pw().print("[");

+				}

+			} else {

+				pw().print("] [");

+			}

+			pw().print(s);

+		}

+		if(!first) {

+			pw().print(']');

+		}

+		pw().println();

+		reportLine();

+	}

+	

+	public String reportColHead(String format, String ...  args) {

+		pw().format(format,(Object[])args);

+		reportLine();

+		return format;

+	}

+

+	public void reportLine() {

+		for(int i=0;i<lineLength;++i)pw().print('-');

+		pw().println();

+	}

+	

+	protected void setQueryParamsOn(Rcli<?> rcli) {

+		StringBuilder sb=null;

+		String force;

+		if((force=aafcli.forceString())!=null) {

+			sb = new StringBuilder("force=");

+			sb.append(force);

+		}

+		if(aafcli.addRequest()) {

+			if(sb==null) {

+				sb = new StringBuilder("request=true");

+			} else {

+				sb.append("&request=true");

+			}

+		}

+		if(sb!=null && rcli!=null) {

+			rcli.setQueryParams(sb.toString());

+		}

+	}

+//

+//	/**

+//	 * If Force is set, will return True once only, then revert to "FALSE".

+//	 *  

+//	 * @return

+//	 */

+//	protected String checkForce() {

+//		if(TRUE.equalsIgnoreCase(env.getProperty(FORCE, FALSE))) {

+//			env.setProperty(FORCE, FALSE);

+//			return "true";

+//		}

+//		return FALSE;

+//	}

+

+	public String toString() {

+		StringBuilder sb = new StringBuilder();

+		if(parent==null) { // ultimate parent

+			build(sb,null);

+			return sb.toString();

+		} else {

+			return parent.toString();

+		}

+	}

+	

+	public String getOrgRealm() {

+		return env.getProperty(AAF_DEFAULT_REALM);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/Help.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/Help.java
new file mode 100644
index 0000000..af6e071
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/Help.java
@@ -0,0 +1,112 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import java.util.List;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+public class Help extends Cmd {

+	private List<Cmd> cmds;

+

+	public Help(AAFcli aafcli, List<Cmd> cmds) {

+		super(aafcli, "--help", 

+			new Param("-d (more details)", false),

+			new Param("command",false));

+		this.cmds = cmds;

+	}

+

+	@Override

+	public int _exec( int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		boolean first = true;

+		StringBuilder sb = new StringBuilder("AAF Command Line Tool");

+		StringBuilder details;

+		if(aafcli.isDetailed() ){

+			multiChar(sb, 21, '-',0);

+			details=new StringBuilder();// use for temporary writing of details

+		} else {

+			multiChar(sb, 21, '-',0);

+			details = null;

+		}

+		String comp = args.length>idx?args[idx++]:null;

+		if("help".equalsIgnoreCase(comp)) {

+			build(sb,null);

+			detailedHelp(4, sb);

+			sb.append('\n');

+		} else {

+		    for(Cmd c : cmds) {

+		    	if(comp!=null) {

+		    		if(comp.equals(c.getName())) {

+		    			multiChar(sb,2,' ',0);

+		    			c.build(sb,details);

+		    		}

+		    	} else {

+		    		if(first) {

+		    			first=false;

+		    		} else {

+		    			multiChar(sb,80,'-',2);

+		    		}

+		    		multiChar(sb,2,' ',0);

+		    		c.build(sb,details);

+		    		if(details!=null) {

+		    			c.detailedHelp(4, sb);

+//					multiChar(sb,80,'-',2);

+		    		}

+		    	}

+		    }

+		}

+		pw().println(sb.toString());

+		return HttpStatus.OK_200;

+	}

+	

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"To print main help, enter \"aafcli\" or \"aafcli --help \"");

+		detailLine(sb,indent,"To print narrow the help content, enter sub-entries after aafcli,");

+		detailLine(sb,indent+2,"i.e. \"aafcli perm\"");

+		detailLine(sb,indent,"To see version of AAF CLI, enter \"aafcli --version \"");

+		sb.append('\n');

+		detailLine(sb,indent,"State Commands: change variables or credentials between calls.");

+		indent+=4;

+		detailLine(sb,indent,"set <tag>=<value>   - Set any System Property to a new value");

+		detailLine(sb,indent,"as <id:password>    - Change Credentials.  Password may be encrypted");

+		detailLine(sb,indent,"expect <int> [int]* - In test mode, check for proper HTTP Status Codes");

+		detailLine(sb,indent,"sleep <int>         - Wait for <int> seconds");

+		sb.append('\n');

+		detailLine(sb,indent-4,"CmdLine Arguments: change behavior of the aafcli program");

+		detailLine(sb,indent,"-i - Read commands from Shell Standard Input");

+		detailLine(sb,indent,"-f - Read commands from a file");

+		detailLine(sb,indent,"-a - In test mode, do not stop execution on unexpected error");

+		detailLine(sb,indent,"-t - Test Mode will not print variable fields that could break tc runs");

+		detailLine(sb,indent+6,"such as expiration dates of a credential");

+		detailLine(sb,indent,"-s - Request specific Start Date (not immediately)");

+		detailLine(sb,indent+6,"Format YYYY-MM-DD.  Can also be set with \"set " + Cmd.STARTDATE + "=<value>\"");

+		detailLine(sb,indent,"-e - Set Expiration/End Date, where commands support");

+		detailLine(sb,indent+6,"Format YYYY-MM-DD.  Can also be set with \"set " + Cmd.ENDDATE + "=<value>\"");

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/MessageException.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/MessageException.java
new file mode 100644
index 0000000..f669ca6
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/MessageException.java
@@ -0,0 +1,46 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+/**

+ * 

+ */

+package org.onap.aaf.cmd;

+

+/**

+ * An Exception designed simply to give End User message, no stack trace

+ * 

+ *

+ */

+public class MessageException extends Exception {

+	/**

+	 * 

+	 */

+	private static final long serialVersionUID = 8143933588878259048L;

+

+	/**

+	 * @param Message

+	 */

+	public MessageException(String msg) {

+		super(msg);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/Param.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/Param.java
new file mode 100644
index 0000000..9e9486a
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/Param.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+public class Param {

+	public final String tag;

+	public final boolean required;

+	

+	/**

+	 * 

+	 * @param t

+	 * @param b

+	 */

+	public Param(String t, boolean required) {

+		tag = t;

+		this.required=required;

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/Version.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/Version.java
new file mode 100644
index 0000000..8cdb27d
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/Version.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.APIException;

+

+public class Version extends Cmd {

+

+

+	public Version(AAFcli aafcli) {

+		super(aafcli, "--version");

+	}

+

+	@Override

+	protected int _exec(int idx, String... args) throws CadiException, APIException, LocatorException {

+		pw().println("AAF Command Line Tool");

+		String version = this.env().getProperty(Config.AAF_DEPLOYED_VERSION, "N/A");

+		pw().println("Version: " + version);

+		return HttpStatus.OK_200;

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Cache.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Cache.java
new file mode 100644
index 0000000..7176d0c
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Cache.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class Cache extends BaseCmd<Mgmt> {

+	public Cache(Mgmt mgmt) throws APIException {

+		super(mgmt, "cache");

+		cmds.add(new Clear(this));

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Clear.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Clear.java
new file mode 100644
index 0000000..296b76d
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Clear.java
@@ -0,0 +1,86 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * p

+ *

+ */

+public class Clear extends Cmd {

+	public Clear(Cache parent) {

+		super(parent,"clear",

+				new Param("name[,name]*",true));

+	}

+

+	@Override

+	public int _exec(int _idx, String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		int rv=409;

+		for(final String name : args[idx++].split(COMMA)) {

+			rv = all(new Retryable<Integer>() {

+				@Override

+				public Integer code(Rcli<?> client) throws APIException, CadiException {

+					int rv = 409;

+					Future<Void> fp = client.delete(

+							"/mgmt/cache/"+name, 

+							Void.class

+							);

+					if(fp.get(AAFcli.timeout())) {

+						pw().println("Cleared Cache for " + name + " on " + client);

+						rv=200;

+					} else {

+						if(rv==409)rv = fp.code();

+						error(fp);

+					}

+					return rv;

+				}

+			});

+		}

+		return rv;

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Clear the cache for certain tables");

+		indent+=2;

+		detailLine(sb,indent,"name        - name of table or 'all'");

+		detailLine(sb,indent+14,"Must have admin rights to '" + Define.ROOT_NS + '\'');

+		indent-=2;

+		api(sb,indent,HttpMethods.DELETE,"mgmt/cache/:name",Void.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Deny.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Deny.java
new file mode 100644
index 0000000..44b3f8f
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Deny.java
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+public class Deny extends BaseCmd<Mgmt> {

+	private final static String[] options = {"add","del"};

+

+	public Deny(Mgmt mgmt) throws APIException {

+		super(mgmt, "deny");

+		cmds.add(new DenySomething(this,"ip","ipv4or6[,ipv4or6]*"));

+		cmds.add(new DenySomething(this,"id","identity[,identity]*"));

+	}

+	

+	public class DenySomething extends Cmd {

+

+		private boolean isID;

+

+		public DenySomething(Deny deny, String type, String repeatable) {

+			super(deny, type,

+				new Param(optionsToString(options),true),

+				new Param(repeatable,true));

+			isID = "id".equals(type);

+		}

+

+		@Override

+		protected int _exec(int _idx, String... args) throws CadiException, APIException, LocatorException {

+		        int idx = _idx;

+			String action = args[idx++];

+			final int option = whichOption(options, action);

+			int rv=409;

+			for(final String name : args[idx++].split(COMMA)) {

+				final String append;

+				if(isID && name.indexOf("@")<0) {

+					append='@'+ env.getProperty(AAFcli.AAF_DEFAULT_REALM);

+				} else {

+					append = "";

+				}

+				final String path = "/mgmt/deny/"+getName() + '/'+ name + append;

+				rv = all(new Retryable<Integer>() {

+					@Override

+					public Integer code(Rcli<?> client) throws APIException, CadiException  {

+						int rv = 409;

+						Future<Void> fp;

+						String resp;

+						switch(option) {

+							case 0: 

+								fp = client.create(path, Void.class);

+								resp = " added";

+								break;

+							default: 

+								fp = client.delete(path, Void.class);

+								resp = " deleted";

+						}

+						if(fp.get(AAFcli.timeout())) {

+							pw().println(name + append + resp + " on " + client);

+							rv=fp.code();

+						} else {

+							if(rv==409)rv = fp.code();

+							error(fp);

+						}

+						return rv;

+					}

+				});

+			}

+			return rv;

+		}

+

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Log.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Log.java
new file mode 100644
index 0000000..5726d31
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Log.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+public class Log extends BaseCmd<Mgmt> {

+	private final static String[] options = {"add","del"};

+

+	public Log(Mgmt mgmt) throws APIException {

+		super(mgmt, "log",

+				new Param(optionsToString(options),true),

+				new Param("id[,id]*",true));

+	}

+	

+	@Override

+	public int _exec(int _idx, String ... args) throws CadiException, APIException, LocatorException {

+		int rv=409;

+		int idx = _idx;

+		final int option = whichOption(options, args[idx++]);

+

+		for(String name : args[idx++].split(COMMA)) {

+			final String fname;

+			if(name.indexOf("@")<0) {

+				fname=name+'@'+ env.getProperty(AAFcli.AAF_DEFAULT_REALM);

+			} else {

+				fname = name;

+			}

+			

+			

+

+			rv = all(new Retryable<Integer>() {

+				@Override

+				public Integer code(Rcli<?> client) throws APIException, CadiException {

+					int rv = 409;

+					Future<Void> fp;

+					String str = "/mgmt/log/id/"+fname;

+					String msg;

+					switch(option) {

+						case 0:	

+							fp = client.create(str,Void.class);

+							msg = "Added";

+							break;

+						case 1:

+							fp = client.delete(str,Void.class);

+							msg = "Deleted";

+							break;

+						default:

+							fp = null;

+							msg = "Ignored";

+					}

+							

+					if(fp!=null) {

+						if(fp.get(AAFcli.timeout())) {

+							pw().println(msg + " Special Log for " + fname + " on " + client);

+							rv=200;

+						} else {

+							if(rv==409)rv = fp.code();

+							error(fp);

+						}

+						return rv;

+					}

+					return rv;

+				}

+			});

+		}

+		return rv;

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Clear the cache for certain tables");

+		indent+=2;

+		detailLine(sb,indent,"name        - name of table or 'all'");

+		detailLine(sb,indent+14,"Must have admin rights to '" + Define.ROOT_NS + '\'');

+		indent-=2;

+		api(sb,indent,HttpMethods.DELETE,"mgmt/cache/:name",Void.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Mgmt.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Mgmt.java
new file mode 100644
index 0000000..d52b60f
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Mgmt.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class Mgmt extends BaseCmd<Mgmt> {

+	public Mgmt(AAFcli aafcli) throws APIException {

+		super(aafcli, "mgmt");

+		cmds.add(new Cache(this));

+		cmds.add(new Deny(this));

+		cmds.add(new Log(this));

+		cmds.add(new Session(this));

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/SessClear.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/SessClear.java
new file mode 100644
index 0000000..5941a52
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/SessClear.java
@@ -0,0 +1,84 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * p

+ *

+ */

+public class SessClear extends Cmd {

+	public SessClear(Session parent) {

+		super(parent,"clear",

+				new Param("machine",true));

+	}

+

+	@Override

+	public int _exec(int idx, String ... args) throws CadiException, APIException, LocatorException {

+		int rv=409;

+		String machine = args[idx++];

+		rv = oneOf(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws APIException, CadiException {

+				int rv = 409;

+				Future<Void> fp = client.delete(

+						"/mgmt/dbsession", 

+						Void.class

+						);

+				if(fp.get(AAFcli.timeout())) {

+					pw().println("Cleared DBSession on " + client);

+					rv=200;

+				} else {

+					if(rv==409)rv = fp.code();

+					error(fp);

+				}

+				return rv;

+			}

+		},machine);

+		return rv;

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Clear the cache for certain tables");

+		indent+=2;

+		detailLine(sb,indent,"name        - name of table or 'all'");

+		detailLine(sb,indent+14,"Must have admin rights to '" + Define.ROOT_NS + '\'');

+		indent-=2;

+		api(sb,indent,HttpMethods.DELETE,"mgmt/cache/:name",Void.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Session.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Session.java
new file mode 100644
index 0000000..b49e523
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/mgmt/Session.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class Session extends BaseCmd<Mgmt> {

+	public Session(Mgmt mgmt) throws APIException {

+		super(mgmt, "dbsession");

+		cmds.add(new SessClear(this));

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Admin.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Admin.java
new file mode 100644
index 0000000..ff105ce
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Admin.java
@@ -0,0 +1,106 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+public class Admin extends BaseCmd<NS> {

+	private final static String[] options = {"add","del"};

+

+	public Admin(NS ns) throws APIException {

+		super(ns,"admin",

+				new Param(optionsToString(options),true),

+				new Param("name",true),

+				new Param("id[,id]*",true)

+		);

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	    	int idx = _idx;

+		final int option = whichOption(options, args[idx++]);

+		final String ns = args[idx++];

+		final String ids[] = args[idx++].split(",");

+		final String realm = getOrgRealm();

+//		int rv = 500;

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {	

+				Future<Void> fp = null;

+				for(String id : ids) {

+					if (id.indexOf('@') < 0 && realm != null) id += '@' + realm;

+					String verb;

+					switch(option) {

+						case 0: 

+							fp = client.create("/authz/ns/"+ns+"/admin/"+id,Void.class);

+							verb = " added to ";

+							break;

+						case 1: 

+							fp = client.delete("/authz/ns/"+ns+"/admin/"+id,Void.class);

+							verb = " deleted from ";

+							break;

+						default:

+							throw new CadiException("Bad Argument");

+					};

+				

+					if(fp.get(AAFcli.timeout())) {

+						pw().append("Admin ");

+						pw().append(id);

+						pw().append(verb);

+						pw().println(ns);

+					} else {

+						error(fp);

+						return fp.code();

+					}

+					

+				}

+				return fp==null?500:fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	    	int indent = _indent;

+		detailLine(sb,indent,"Add or Delete Administrator to/from Namespace");

+		indent+=4;

+		detailLine(sb,indent,"name - Name of Namespace");

+		detailLine(sb,indent,"id   - Credential of Person(s) to be Administrator");

+		sb.append('\n');

+		detailLine(sb,indent,"aafcli will call API on each ID presented.");

+		indent-=4;

+		api(sb,indent,HttpMethods.POST,"authz/ns/<ns>/admin/<id>",Void.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/ns/<ns>/admin/<id>",Void.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Attrib.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Attrib.java
new file mode 100644
index 0000000..97e2e9a
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Attrib.java
@@ -0,0 +1,115 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+public class Attrib extends BaseCmd<NS> {

+	private final static String[] options = {"add","upd","del"};

+

+	public Attrib(NS ns) throws APIException {

+		super(ns,"attrib",

+				new Param(optionsToString(options),true),

+				new Param("ns",true),

+				new Param("key",true),

+				new Param("value",false)

+		);

+	}

+

+	@Override

+	public int _exec(final int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final int option = whichOption(options, args[idx]);

+		final String ns = args[idx+1];

+		final String key = args[idx+2];

+		final String value;

+		if(option!=2) {

+			if(args.length<=idx+3) {

+				throw new CadiException("Not added: Need more Data");

+			}

+			value = args[idx+3];

+		} else {

+			value = "";

+		}

+		

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {	

+				Future<Void> fp = null;

+				String message;

+				switch(option) {

+					case 0: 

+						fp = client.create("/authz/ns/"+ns+"/attrib/"+key+'/'+value,Void.class);

+						message = String.format("Add Attrib %s=%s to %s",

+								key,value,ns);

+						break;

+					case 1: 

+						fp = client.update("/authz/ns/"+ns+"/attrib/"+key+'/'+value);

+						message = String.format("Update Attrib %s=%s for %s",

+								key,value,ns);

+						break;

+					case 2: 

+						fp = client.delete("/authz/ns/"+ns+"/attrib/"+key,Void.class);

+						message = String.format("Attrib %s deleted from %s",

+								key,ns);

+						break;

+					default:

+						throw new CadiException("Bad Argument");

+				};

+			

+				if(fp.get(AAFcli.timeout())) {

+					pw().println(message);

+				} else {

+					error(fp);

+					return fp.code();

+				}

+					

+				return fp==null?500:fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	    	int indent = _indent;

+		detailLine(sb,indent,"Add or Delete Administrator to/from Namespace");

+		indent+=4;

+		detailLine(sb,indent,"name - Name of Namespace");

+		detailLine(sb,indent,"id   - Credential of Person(s) to be Administrator");

+		sb.append('\n');

+		detailLine(sb,indent,"aafcli will call API on each ID presented.");

+		indent-=4;

+		api(sb,indent,HttpMethods.POST,"authz/ns/<ns>/admin/<id>",Void.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/ns/<ns>/admin/<id>",Void.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Create.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Create.java
new file mode 100644
index 0000000..32ab43f
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Create.java
@@ -0,0 +1,128 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.NsRequest;

+

+/**

+ * p

+ *

+ */

+public class Create extends Cmd {

+	private static final String COMMA = ",";

+

+	public Create(NS parent) {

+		super(parent,"create", 

+				new Param("name",true),

+				new Param("responsible (id[,id]*)",true), 

+				new Param("admin (id[,id]*)",false));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	    	int idx = _idx;

+

+		final NsRequest nr = new NsRequest();

+		

+		String realm = getOrgRealm();

+		

+		nr.setName(args[idx++]);

+		String[] responsible = args[idx++].split(COMMA);

+		for(String s : responsible) {

+			if (s.indexOf('@') < 0 && realm != null) s += '@' + realm;

+			nr.getResponsible().add(s);

+		}

+		String[] admin;

+		if(args.length>idx) {

+			admin = args[idx++].split(COMMA);

+		} else {

+			admin = responsible;

+		}

+		for(String s : admin) {

+			if (s.indexOf('@') < 0 && realm != null) s += '@' + realm;

+			nr.getAdmin().add(s);

+		}

+		

+		// Set Start/End commands

+		setStartEnd(nr);

+		

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				// Requestable

+				setQueryParamsOn(client);

+				Future<NsRequest> fp = client.create(

+						"/authz/ns", 

+						getDF(NsRequest.class),

+						nr

+						);

+				if(fp.get(AAFcli.timeout())) {

+					pw().println("Created Namespace");

+				} else {

+					if(fp.code()==202) {

+						pw().println("Namespace Creation Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	    	int indent = _indent;

+		detailLine(sb,indent,"Create a Namespace");

+		indent+=2;

+		detailLine(sb,indent,"name        - Namespaces are dot-delimited, ex com.att.myapp");

+		detailLine(sb,indent+14,"and must be created with parent credentials.");

+		detailLine(sb,indent+14,"Ex: to create com.att.myapp, you must be admin for com.att");

+		detailLine(sb,indent+14,"or com");

+		detailLine(sb,indent,"responsible - This is the person(s) who receives Notifications and");

+		detailLine(sb,indent+14,"approves Requests regarding this Namespace. Companies have");

+		detailLine(sb,indent+14,"Policies as to who may take on this responsibility");

+		detailLine(sb,indent,"admin       - These are the people who are allowed to make changes on");

+		detailLine(sb,indent+14,"the Namespace, including creating Roles, Permissions");

+		detailLine(sb,indent+14,"and Credentials");

+		sb.append('\n');

+		detailLine(sb,indent,"Namespaces can be created even though there are Roles/Permissions which");

+		detailLine(sb,indent,"start with the requested sub-namespace.  They are reassigned to the");

+		detailLine(sb,indent,"Child Namespace");

+		indent-=2;

+		api(sb,indent,HttpMethods.POST,"authz/ns",NsRequest.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Delete.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Delete.java
new file mode 100644
index 0000000..5254d46
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Delete.java
@@ -0,0 +1,90 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+/**

+ * p

+ *

+ */

+public class Delete extends Cmd {

+	public Delete(NS parent) {

+		super(parent,"delete", 

+				new Param("name",true)); 

+	}

+

+	@Override

+	public int _exec(final int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int index = idx;

+				StringBuilder path = new StringBuilder("/authz/ns/");

+				path.append(args[index++]);

+				

+				// Send "Force" if set

+				setQueryParamsOn(client);

+				Future<Void> fp = client.delete(path.toString(),Void.class);

+				

+				if(fp.get(AAFcli.timeout())) {

+					pw().println("Deleted Namespace");

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Delete a Namespace");

+		indent+=4;

+		detailLine(sb,indent,"Namespaces cannot normally be deleted when there are still credentials,");

+		detailLine(sb,indent,"permissions or roles associated with them. These can be deleted");

+		detailLine(sb,indent,"automatically by setting \"force\" property.");

+		detailLine(sb,indent,"i.e. set force=true or just starting with \"force\"");

+		detailLine(sb,indent," (note force is unset after first use)");

+		sb.append('\n');

+		detailLine(sb,indent,"If \"set force=move\" is set, credentials are deleted, but ");

+		detailLine(sb,indent,"Permissions and Roles are assigned to the Parent Namespace instead of");

+		detailLine(sb,indent,"being deleted.  Similarly, Namespaces can be created even though there");

+		detailLine(sb,indent,"are Roles/Perms whose type starts with the requested sub-namespace.");

+		detailLine(sb,indent,"They are simply reassigned to the Child Namespace");

+		indent-=4;

+		api(sb,indent,HttpMethods.DELETE,"authz/ns/<ns>[?force=true]",Void.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Describe.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Describe.java
new file mode 100644
index 0000000..2939964
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Describe.java
@@ -0,0 +1,96 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.NsRequest;

+

+public class Describe extends Cmd {

+	private static final String NS_PATH = "/authz/ns";

+	public Describe(NS parent) {

+		super(parent,"describe", 

+				new Param("name",true),

+				new Param("description",true)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String name = args[idx++];

+				StringBuilder desc = new StringBuilder();

+				while (idx < args.length) {

+					desc.append(args[idx++] + ' ');

+				}

+		

+				NsRequest nsr = new NsRequest();

+				nsr.setName(name);

+				nsr.setDescription(desc.toString());

+		

+				// Set Start/End commands

+				setStartEnd(nsr);

+				

+				Future<NsRequest> fn = null;

+				int rv;

+

+				fn = client.update(

+					NS_PATH,

+					getDF(NsRequest.class),

+					nsr

+					);

+

+				if(fn.get(AAFcli.timeout())) {

+					rv=fn.code();

+					pw().println("Description added to Namespace");

+				} else {

+					if((rv=fn.code())==202) {

+						pw().print("Adding description");

+						pw().println(" Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fn);

+					}

+				}

+				return rv;

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Add a description to a namespace");

+		api(sb,indent,HttpMethods.PUT,"authz/ns",NsRequest.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/List.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/List.java
new file mode 100644
index 0000000..47c9a25
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/List.java
@@ -0,0 +1,170 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.inno.env.util.Chrono;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+import aaf.v2_0.Nss.Ns.Attrib;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Roles;

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+public class List extends BaseCmd<NS> {

+

+	public List(NS parent) {

+		super(parent,"list");

+		cmds.add(new ListByName(this));

+		

+//		TODO: uncomment when on cassandra 2.1.2 if we like cli command to get all ns's 

+//				a user is admin or responsible for 

+		cmds.add(new ListAdminResponsible(this));

+		

+		cmds.add(new ListActivity(this));

+		cmds.add(new ListUsers(this));

+		cmds.add(new ListChildren(this));

+		cmds.add(new ListNsKeysByAttrib(this));

+	}

+

+	private static final String sformat = "        %-72s\n";

+	protected static final String kformat = "  %-72s\n";

+

+	

+	public void report(Future<Nss> fp, String ... str) {

+		reportHead(str);

+		if(fp==null) {

+			pw().println("    *** Namespace Not Found ***");

+		}

+		

+		if(fp!=null && fp.value!=null) {

+		    for(Ns ns : fp.value.getNs()) {

+		    	pw().println(ns.getName());

+		    	if (this.aafcli.isDetailed()) {

+		    		pw().println("    Description");

+		    		pw().format(sformat,ns.getDescription()==null?"":ns.getDescription());

+		    	}

+		    	if(ns.getAdmin().size()>0) {

+		    		pw().println("    Administrators");

+		    		for(String admin : ns.getAdmin()) {

+		    			pw().format(sformat,admin);

+		    		}

+		    	}

+		    	if(ns.getResponsible().size()>0) {

+		    		pw().println("    Responsible Parties");

+		    		for(String responsible : ns.getResponsible()) {

+		    			pw().format(sformat,responsible);

+		    		}

+		    	}

+		    	if(ns.getAttrib().size()>0) {

+		    		pw().println("    Namespace Attributes");

+		    		for(Attrib attrib : ns.getAttrib()) {

+		    			StringBuilder sb = new StringBuilder(attrib.getKey());

+		    			if(attrib.getValue()==null || attrib.getValue().length()>0) {

+		    				sb.append('=');

+		    				sb.append(attrib.getValue());

+		    			}

+		    			pw().format(sformat,sb.toString());

+		    		}

+		    		

+		    	}

+		    }

+		}

+	}

+	

+	public void reportName(Future<Nss> fp, String ... str) {

+		reportHead(str);

+		if(fp!=null && fp.value!=null) {

+			java.util.List<Ns> nss = fp.value.getNs();

+			Collections.sort(nss, new Comparator<Ns>() {

+				@Override

+				public int compare(Ns ns1, Ns ns2) {

+					return ns1.getName().compareTo(ns2.getName());

+				}

+			});

+			

+			for(Ns ns : nss) {

+				pw().println(ns.getName());

+				if (this.aafcli.isDetailed() && ns.getDescription() != null) {

+				    pw().println("   " + ns.getDescription());

+				}

+			}

+		}

+	}

+

+	public void reportRole(Future<Roles> fr) {

+		if(fr!=null && fr.value!=null && fr.value.getRole().size()>0) {

+			pw().println("    Roles");

+			for(aaf.v2_0.Role r : fr.value.getRole()) {

+				pw().format(sformat,r.getName());

+			}

+		}

+	}

+

+	private static final String pformat = "        %-30s %-24s %-15s\n";

+	public void reportPerm(Future<Perms> fp) {

+		if(fp!=null && fp.value!=null && fp.value.getPerm().size()>0) {

+			pw().println("    Permissions");

+			for(aaf.v2_0.Perm p : fp.value.getPerm()) {

+				pw().format(pformat,p.getType(),p.getInstance(),p.getAction());

+			}

+		}

+	}

+	

+	

+	private static final String cformat = "        %-30s %-6s %-24s\n";

+	public void reportCred(Future<Users> fc) {		

+		if(fc!=null && fc.value!=null && fc.value.getUser().size()>0) {

+			pw().println("    Credentials");

+			java.util.List<User> users = fc.value.getUser();

+			Collections.sort(users, new Comparator<User>() {

+				@Override

+				public int compare(User u1, User u2) {

+					return u1.getId().compareTo(u2.getId());

+				}

+			});

+			for(aaf.v2_0.Users.User u : users) {

+				if (this.aafcli.isTest()) {

+				    pw().format(sformat,u.getId());

+				} else {

+					String type;

+					switch(u.getType()) {

+						case 1:   type = "U/P"; break;

+						case 10:  type="Cert"; break;

+						case 200: type="x509"; break;

+						default:  type = "";

+					}

+					pw().format(cformat,u.getId(),type,Chrono.niceDateStamp(u.getExpires()));

+				}

+			}

+		}

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListActivity.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListActivity.java
new file mode 100644
index 0000000..74bcb92
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListActivity.java
@@ -0,0 +1,81 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.History;

+

+/**

+ *

+ */

+public class ListActivity extends Cmd {

+	private static final String HEADER = "List Activity of Namespace";

+	

+	public ListActivity(List parent) {

+		super(parent,"activity", 

+				new Param("name",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String ns = args[idx++];

+		

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<History> fp = client.read(

+						"/authz/hist/ns/"+ns, 

+						getDF(History.class)

+						);

+	

+				if(fp.get(AAFcli.timeout())) {

+					activity(fp.value, HEADER + " [ " + ns + " ]");

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/hist/ns/<ns>",History.class,true);

+	}

+

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListAdminResponsible.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListAdminResponsible.java
new file mode 100644
index 0000000..87ed924
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListAdminResponsible.java
@@ -0,0 +1,79 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+

+public class ListAdminResponsible extends Cmd {

+	private static final String HEADER="List Namespaces with ";

+	private final static String[] options = {"admin","responsible"};

+	

+	public ListAdminResponsible(List parent) {

+		super(parent,null, 

+				new Param(optionsToString(options),true),

+				new Param("user",true)); 

+	}

+

+	@Override

+	protected int _exec(final int index, final String... args) throws CadiException, APIException, LocatorException {

+

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String title = args[idx++];

+				String user = args[idx++];

+				if (user.indexOf('@') < 0 && getOrgRealm() != null) user += '@' + getOrgRealm();

+				

+				Future<Nss> fn = client.read("/authz/nss/"+title+"/"+user,getDF(Nss.class));

+				if(fn.get(AAFcli.timeout())) {

+					((List)parent).reportName(fn,HEADER + title + " privileges for ",user);

+				} else if(fn.code()==404) {

+					((List)parent).report(null,HEADER + title + " privileges for ",user);

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER + "admin or responsible priveleges for user");

+		api(sb,indent,HttpMethods.GET,"authz/nss/<admin|responsible>/<user>",Nss.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListByName.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListByName.java
new file mode 100644
index 0000000..a63aacf
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListByName.java
@@ -0,0 +1,105 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Roles;

+import aaf.v2_0.Users;

+

+/**

+ *

+ */

+public class ListByName extends Cmd {

+	private static final String HEADER="List Namespaces by Name";

+	

+	public ListByName(List parent) {

+		super(parent,"name", 

+				new Param("ns",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String ns=args[idx++];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Nss> fn = client.read("/authz/nss/"+ns,getDF(Nss.class));

+				if(fn.get(AAFcli.timeout())) {

+					((List)parent).report(fn,HEADER,ns);

+					if(fn.value!=null) {

+						for(Ns n : fn.value.getNs()) {

+							Future<Roles> fr = client.read("/authz/roles/ns/"+n.getName(), getDF(Roles.class));

+							if(fr.get(AAFcli.timeout())) {

+								((List)parent).reportRole(fr);

+							}

+						}

+						for(Ns n : fn.value.getNs()) {

+							Future<Perms> fp = client.read("/authz/perms/ns/"+n.getName(), getDF(Perms.class));

+							if(fp.get(AAFcli.timeout())) {

+								((List)parent).reportPerm(fp);

+							}

+						}

+						for(Ns n : fn.value.getNs()) {

+							Future<Users> fu = client.read("/authn/creds/ns/"+n.getName(), getDF(Users.class));

+							if(fu.get(AAFcli.timeout())) {

+								((List)parent).reportCred(fu);

+							}

+						}

+					}

+				} else if(fn.code()==404) {

+					((List)parent).report(null,HEADER,ns);

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);

+		detailLine(sb,indent,"Indirectly uses:");

+		api(sb,indent,HttpMethods.GET,"authz/roles/ns/<ns>",Roles.class,false);

+		api(sb,indent,HttpMethods.GET,"authz/perms/ns/<ns>",Perms.class,false);

+		api(sb,indent,HttpMethods.GET,"authn/creds/ns/<ns>",Users.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListChildren.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListChildren.java
new file mode 100644
index 0000000..670729e
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListChildren.java
@@ -0,0 +1,82 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+

+/**

+ * p

+ *

+ */

+public class ListChildren extends Cmd {

+	private static final String HEADER="List Child Namespaces";

+	

+	public ListChildren(List parent) {

+		super(parent,"children", 

+				new Param("ns",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String ns=args[idx++];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Nss> fn = client.read("/authz/nss/children/"+ns,getDF(Nss.class));

+				if(fn.get(AAFcli.timeout())) {

+					parent.reportHead(HEADER);

+					for(Ns ns : fn.value.getNs()) {

+						pw().format(List.kformat, ns.getName());

+					}

+				} else if(fn.code()==404) {

+					((List)parent).report(null,HEADER,ns);

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/nss/children/<ns>",Nss.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListNsKeysByAttrib.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListNsKeysByAttrib.java
new file mode 100644
index 0000000..516bcd3
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListNsKeysByAttrib.java
@@ -0,0 +1,89 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Keys;

+import aaf.v2_0.Nss;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Roles;

+import aaf.v2_0.Users;

+

+/**

+ * p

+ *

+ */

+public class ListNsKeysByAttrib extends Cmd {

+	private static final String HEADER="List Namespace Names by Attribute";

+	

+	public ListNsKeysByAttrib(List parent) {

+		super(parent,"keys", 

+				new Param("attrib",true)); 

+	}

+

+	@Override

+	public int _exec(final int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final String attrib=args[idx];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Keys> fn = client.read("/authz/ns/attrib/"+attrib,getDF(Keys.class));

+				if(fn.get(AAFcli.timeout())) {

+					parent.reportHead(HEADER);

+					for(String key : fn.value.getKey()) {

+						pw().printf(List.kformat, key);

+					}

+				} else if(fn.code()==404) {

+					parent.reportHead(HEADER);

+					pw().println("    *** No Namespaces Found ***");

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);

+		detailLine(sb,indent,"Indirectly uses:");

+		api(sb,indent,HttpMethods.GET,"authz/roles/ns/<ns>",Roles.class,false);

+		api(sb,indent,HttpMethods.GET,"authz/perms/ns/<ns>",Perms.class,false);

+		api(sb,indent,HttpMethods.GET,"authn/creds/ns/<ns>",Users.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsers.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsers.java
new file mode 100644
index 0000000..f035901
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsers.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import javax.xml.datatype.XMLGregorianCalendar;

+

+import org.onap.aaf.cmd.BaseCmd;

+

+import aaf.v2_0.Users.User;

+

+public class ListUsers extends BaseCmd<List> {

+	

+	public ListUsers(List parent) {

+		super(parent,"user");

+		cmds.add(new ListUsersWithPerm(this));

+		cmds.add(new ListUsersInRole(this));

+	}

+

+	public void report(String header, String ns) {

+		((List)parent).report(null, header,ns);

+	}

+

+	public void report(String subHead) {

+		pw().println(subHead);

+	}

+

+	private static final String uformat = "%s%-50s expires:%02d/%02d/%04d\n";

+	public void report(String prefix, User u) {

+		XMLGregorianCalendar xgc = u.getExpires();

+		pw().format(uformat,prefix,u.getId(),xgc.getMonth()+1,xgc.getDay(),xgc.getYear());

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersInRole.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersInRole.java
new file mode 100644
index 0000000..8fdee9b
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersInRole.java
@@ -0,0 +1,129 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import java.util.HashSet;

+import java.util.Set;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+import aaf.v2_0.Role;

+import aaf.v2_0.Roles;

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+/**

+ * p

+ *

+ */

+public class ListUsersInRole extends Cmd {

+	private static final String HEADER="List Users in Roles of Namespace ";

+	

+	public ListUsersInRole(ListUsers parent) {

+		super(parent,"role", 

+				new Param("ns",true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String ns=args[idx++];

+		final boolean detail = aafcli.isDetailed();

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				((ListUsers)parent).report(HEADER,ns);

+				Future<Nss> fn = client.read("/authz/nss/"+ns,getDF(Nss.class));

+				if(fn.get(AAFcli.timeout())) {

+					if(fn.value!=null) {

+						Set<String> uset = detail?null:new HashSet<String>();

+						for(Ns n : fn.value.getNs()) {

+							Future<Roles> fr = client.read("/authz/roles/ns/"+n.getName(), getDF(Roles.class));

+							if(fr.get(AAFcli.timeout())) {

+								for(Role r : fr.value.getRole()) {

+									if(detail) {

+										((ListUsers)parent).report(r.getName());

+									}

+									Future<Users> fus = client.read(

+											"/authz/users/role/"+r.getName(), 

+											getDF(Users.class)

+											);

+									if(fus.get(AAFcli.timeout())) {

+										for(User u : fus.value.getUser()) {

+											if(detail) {

+												((ListUsers)parent).report("  ",u);

+											} else {

+											    uset.add(u.getId());

+											}

+										}

+									} else if(fn.code()==404) {

+										return 200;

+									}

+								}

+							}

+						}

+						if(uset!=null) {

+							for(String u : uset) {

+								pw().print("  ");

+								pw().println(u);

+							}

+						}

+					}

+				} else if(fn.code()==404) {

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=4;

+		detailLine(sb,indent,"Report Users associated with this Namespace's Roles");

+		sb.append('\n');

+		detailLine(sb,indent,"If \"set details=true\" is specified, then all roles are printed ");

+		detailLine(sb,indent,"with the associated users and expiration dates");

+		indent-=4;

+		api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);

+		api(sb,indent,HttpMethods.GET,"authz/roles/ns/<ns>",Roles.class,false);

+		api(sb,indent,HttpMethods.GET,"authz/users/role/<ns>",Users.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersWithPerm.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersWithPerm.java
new file mode 100644
index 0000000..ad65fae
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/ListUsersWithPerm.java
@@ -0,0 +1,128 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import java.util.HashSet;

+import java.util.Set;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+import aaf.v2_0.Perm;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+/**

+ * p

+ *

+ */

+public class ListUsersWithPerm extends Cmd {

+	private static final String HEADER="List Users of Permissions of Namespace ";

+	

+	public ListUsersWithPerm(ListUsers parent) {

+		super(parent,"perm", 

+				new Param("ns",true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String ns=args[idx++];

+		final boolean detail = aafcli.isDetailed();

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				((ListUsers)parent).report(HEADER,ns);

+				Future<Nss> fn = client.read("/authz/nss/"+ns,getDF(Nss.class));

+				if(fn.get(AAFcli.timeout())) {

+					if(fn.value!=null) {

+						Set<String> uset = detail?null:new HashSet<String>();

+						

+						for(Ns n : fn.value.getNs()) {

+							Future<Perms> fp = client.read("/authz/perms/ns/"+n.getName(), getDF(Perms.class));

+							if(fp.get(AAFcli.timeout())) {

+								for(Perm p : fp.value.getPerm()) {

+									String perm = p.getType()+'/'+p.getInstance()+'/'+p.getAction();

+									if(detail)((ListUsers)parent).report(perm);

+									Future<Users> fus = client.read(

+											"/authz/users/perm/"+perm, 

+											getDF(Users.class)

+											);

+									if(fus.get(AAFcli.timeout())) {

+										for(User u : fus.value.getUser()) {

+											if(detail)

+												((ListUsers)parent).report("  ",u);

+											else 

+												uset.add(u.getId());

+										}

+									} else if(fn.code()==404) {

+										return 200;

+									}

+								}

+							}

+						}

+						if(uset!=null) {

+							for(String u : uset) {

+								pw().print("  ");

+								pw().println(u);

+							}

+						}

+					}

+				} else if(fn.code()==404) {

+					return 200;

+				} else {	

+					error(fn);

+				}

+				return fn.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=4;

+		detailLine(sb,indent,"Report Users associated with this Namespace's Permissions");

+		sb.append('\n');

+		detailLine(sb,indent,"If \"set detail=true\" is specified, then Permissions are printed with the associated");

+		detailLine(sb,indent,"users and expiration dates");

+		indent-=4;

+		api(sb,indent,HttpMethods.GET,"authz/nss/<ns>",Nss.class,true);

+		api(sb,indent,HttpMethods.GET,"authz/perms/ns/<ns>",Perms.class,false);

+		api(sb,indent,HttpMethods.GET,"authz/users/perm/<type>/<instance>/<action>",Users.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/NS.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/NS.java
new file mode 100644
index 0000000..979e418
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/NS.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class NS extends BaseCmd<NS> {

+//	final Role role;

+

+	public NS(AAFcli aafcli) throws APIException {

+		super(aafcli, "ns");

+//		this.role = role;

+	

+		cmds.add(new Create(this));

+		cmds.add(new Delete(this));

+		cmds.add(new Admin(this));

+		cmds.add(new Responsible(this));

+		cmds.add(new Describe(this));

+		cmds.add(new Attrib(this));

+		cmds.add(new List(this));

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Responsible.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Responsible.java
new file mode 100644
index 0000000..e84bd4d
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/ns/Responsible.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+public class Responsible extends BaseCmd<NS> {

+	private final static String[] options = {"add","del"};

+

+	public Responsible(NS ns) throws APIException {

+		super(ns,"responsible",

+				new Param(optionsToString(options),true),

+				new Param("name",true),

+				new Param("id[,id]*",true)

+		);

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	    	int idx = _idx;

+

+		final int option = whichOption(options, args[idx++]);

+		final String ns = args[idx++];

+		final String ids[] = args[idx++].split(",");

+		final String realm = getOrgRealm();

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Void> fp=null;

+				for(String id : ids) {

+					if (id.indexOf('@') < 0 && realm != null) id += '@' + realm;

+					String verb;

+					switch(option) {

+						case 0: 

+							fp = client.create("/authz/ns/"+ns+"/responsible/"+id,Void.class);

+							verb = " is now ";

+							break;

+						case 1: 

+							fp = client.delete("/authz/ns/"+ns+"/responsible/"+id,Void.class);

+							verb = " is no longer ";

+							break;

+						default:

+							throw new CadiException("Bad Argument");

+					};

+				

+					if(fp.get(AAFcli.timeout())) {

+						pw().append(id);

+						pw().append(verb);

+						pw().append("responsible for ");

+						pw().println(ns);

+					} else {

+						error(fp);

+						return fp.code();

+					}

+				}

+				return fp==null?500:fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	    	int indent = _indent;

+		detailLine(sb,indent,"Add or Delete Responsible person to/from Namespace");

+		indent+=2;

+		detailLine(sb,indent,"Responsible persons receive Notifications and approve Requests ");

+		detailLine(sb,indent,"regarding this Namespace. Companies have Policies as to who may");

+		detailLine(sb,indent,"take on this responsibility");

+

+		indent+=2;

+		detailLine(sb,indent,"name - Name of Namespace");

+		detailLine(sb,indent,"id   - Credential of Person(s) to be made responsible");

+		sb.append('\n');

+		detailLine(sb,indent,"aafcli will call API on each ID presented.");

+		indent-=4;

+		api(sb,indent,HttpMethods.POST,"authz/ns/<ns>/responsible/<id>",Void.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/ns/<ns>/responsible/<id>",Void.class,false);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Create.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Create.java
new file mode 100644
index 0000000..2c49269
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Create.java
@@ -0,0 +1,165 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.PermRequest;

+import aaf.v2_0.RoleRequest;

+

+/**

+ * 

+ *

+ */

+public class Create extends Cmd {

+	public Create(Perm parent) {

+		super(parent,"create", 

+				new Param("type",true), 

+				new Param("instance",true),

+				new Param("action", true),

+				new Param("role[,role]* (to Grant to)", false)

+				);

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				final PermRequest pr = new PermRequest();  

+				pr.setType(args[idx++]);

+				pr.setInstance(args[idx++]);

+				pr.setAction(args[idx++]);

+				String roleCommas = (args.length>idx)?args[idx++]:null;

+				String[] roles = roleCommas==null?null:roleCommas.split("\\s*,\\s*");

+				boolean force = aafcli.forceString()!=null;

+				int rv;

+				

+				if(roles!=null && force) { // Make sure Roles are Created

+					RoleRequest rr = new RoleRequest();

+					for(String role : roles) {

+						rr.setName(role);;

+						Future<RoleRequest> fr = client.create(

+							"/authz/role",

+							getDF(RoleRequest.class),

+							rr

+							);

+						fr.get(AAFcli.timeout());

+						switch(fr.code()){

+							case 201:

+								pw().println("Created Role [" + role + ']');

+								break;

+							case 409:

+								break;

+							default: 

+								pw().println("Role [" + role + "] does not exist, and cannot be created.");

+								return HttpStatus.PARTIAL_CONTENT_206;

+						}

+					}

+				}

+

+				// Set Start/End commands

+				setStartEnd(pr);

+				setQueryParamsOn(client);

+				Future<PermRequest> fp = client.create(

+						"/authz/perm",

+						getDF(PermRequest.class),

+						pr

+						);

+				if(fp.get(AAFcli.timeout())) {

+					rv = fp.code();

+					pw().println("Created Permission");

+					if(roles!=null) {

+						if(aafcli.forceString()!=null) { // Make sure Roles are Created

+							RoleRequest rr = new RoleRequest();

+							for(String role : roles) {

+								rr.setName(role);;

+								Future<RoleRequest> fr = client.create(

+									"/authz/role",

+									getDF(RoleRequest.class),

+									rr

+									);

+								fr.get(AAFcli.timeout());

+								switch(fr.code()){

+									case 201:

+									case 409:break;

+									default: 

+										

+								}

+							}

+						}

+						

+						try {

+							if(201!=(rv=((Perm)parent)._exec(0, 

+									new String[] {"grant",pr.getType(),pr.getInstance(),pr.getAction(),roleCommas}))) {

+								rv = HttpStatus.PARTIAL_CONTENT_206;

+							}

+						} catch (LocatorException e) {

+							throw new CadiException(e);

+						}

+					}

+				} else {

+					rv = fp.code();

+					if(rv==409 && force) {

+						rv = 201;

+					} else if(rv==202) {

+						pw().println("Permission Creation Accepted, but requires Approvals before actualizing");

+						if (roles!=null)

+							pw().println("You need to grant the roles after approval.");

+					} else {

+						error(fp);

+					}

+				}

+				return rv;

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Create a Permission with:");

+		detailLine(sb,indent+=2,"type     - A Namespace qualified identifier identifying the kind of");

+		detailLine(sb,indent+11,"resource to be protected");

+		detailLine(sb,indent,"instance - A name that distinguishes a particular instance of resource");

+		detailLine(sb,indent,"action   - What kind of action is allowed");

+		detailLine(sb,indent,"role(s)  - Perms granted to these Comma separated Role(s)");

+		detailLine(sb,indent+11,"Nonexistent role(s) will be created, if in same namespace");

+		sb.append('\n');

+		detailLine(sb,indent+2,"Note: Instance and Action can be a an '*' (enter \\\\* on Unix Shell)");

+		api(sb,indent,HttpMethods.POST,"authz/perm",PermRequest.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Delete.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Delete.java
new file mode 100644
index 0000000..80bdf4f
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Delete.java
@@ -0,0 +1,90 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.PermRequest;

+

+/**

+ *

+ */

+public class Delete extends Cmd {

+	public Delete(Perm parent) {

+		super(parent,"delete", 

+				new Param("type",true), 

+				new Param("instance",true),

+				new Param("action", true));

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				// Object Style Delete

+				PermRequest pk = new PermRequest();

+				pk.setType(args[idx++]);

+				pk.setInstance(args[idx++]);

+				pk.setAction(args[idx++]);

+		

+				// Set "Force" if set

+				setQueryParamsOn(client);

+				Future<PermRequest> fp = client.delete(

+						"/authz/perm", 

+						getDF(PermRequest.class),

+						pk);

+				if(fp.get(AAFcli.timeout())) {

+					pw().println("Deleted Permission");

+				} else {

+					if(fp.code()==202) {

+						pw().println("Permission Deletion Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Delete a Permission with type,instance and action");

+		detailLine(sb,indent+4,"see Create for definitions");

+		api(sb,indent,HttpMethods.DELETE,"authz/perm",PermRequest.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Describe.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Describe.java
new file mode 100644
index 0000000..8925199
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Describe.java
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.PermRequest;

+

+public class Describe extends Cmd {

+	private static final String PERM_PATH = "/authz/perm";

+	public Describe(Perm parent) {

+		super(parent,"describe", 

+				new Param("type",true),

+				new Param("instance", true),

+				new Param("action", true),

+				new Param("description",true)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String type = args[idx++];

+				String instance = args[idx++];

+				String action = args[idx++];

+				StringBuilder desc = new StringBuilder();

+				while (idx < args.length) {

+					desc.append(args[idx++] + ' ');

+				}

+		

+				PermRequest pr = new PermRequest();

+				pr.setType(type);

+				pr.setInstance(instance);

+				pr.setAction(action);

+				pr.setDescription(desc.toString());

+		

+				// Set Start/End commands

+				setStartEnd(pr);

+				

+				Future<PermRequest> fp = null;

+				int rv;

+

+				fp = client.update(

+					PERM_PATH,

+					getDF(PermRequest.class),

+					pr

+					);

+

+				if(fp.get(AAFcli.timeout())) {

+					rv=fp.code();

+					pw().println("Description added to Permission");

+				} else {

+					if((rv=fp.code())==202) {

+						pw().print("Adding description");

+						pw().println(" Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return rv;

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Add a description to a permission");

+		api(sb,indent,HttpMethods.PUT,"authz/perm",PermRequest.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Grant.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Grant.java
new file mode 100644
index 0000000..d914567
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Grant.java
@@ -0,0 +1,151 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Pkey;

+import aaf.v2_0.RolePermRequest;

+

+/**

+ * 

+ *

+ */

+public class Grant extends Cmd {

+	private final static String[] options = {"grant","ungrant","setTo"};

+

+	public Grant(Perm parent) {

+		super(parent,null,

+			new Param(optionsToString(options),true),

+			new Param("type",true),

+			new Param("instance",true),

+			new Param("action",true),

+			new Param("role[,role]* (!REQ S)",false)

+			); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String action = args[idx++];

+				int option = whichOption(options, action);

+		

+				RolePermRequest rpr = new RolePermRequest();

+				Pkey pk = new Pkey();

+				pk.setType(args[idx++]);

+				pk.setInstance(args[idx++]);

+				pk.setAction(args[idx++]);

+				rpr.setPerm(pk);

+				setStartEnd(rpr);

+				

+				Future<RolePermRequest> frpr = null;

+		

+				if (option != 2) {

+					String[] roles = args[idx++].split(",");

+					String strA,strB;

+					for(String role : roles) {

+						rpr.setRole(role);

+						if(option==0) {

+							// You can request to Grant Permission to a Role

+							setQueryParamsOn(client);

+							frpr = client.create(

+									"/authz/role/perm", 

+									getDF(RolePermRequest.class),

+									rpr

+									);

+							strA = "Granted Permission [";

+							strB = "] to Role [";

+						} else {

+							// You can request to UnGrant Permission to a Role

+							setQueryParamsOn(client);

+							frpr = client.delete(

+									"/authz/role/" + role + "/perm", 

+									getDF(RolePermRequest.class),

+									rpr

+									);

+							strA = "UnGranted Permission [";

+							strB = "] from Role [";

+						}

+						if(frpr.get(AAFcli.timeout())) {

+							pw().println(strA + pk.getType() + '|' + pk.getInstance() + '|' + pk.getAction() 

+									+ strB + role +']');

+						} else {

+							if (frpr.code()==202) {

+								pw().print("Permission Role ");

+								pw().print(option==0?"Granted":"Ungranted");

+								pw().println(" Accepted, but requires Approvals before actualizing");

+							} else {

+								error(frpr);

+								idx=Integer.MAX_VALUE;

+							}			

+						}

+					}

+				} else {

+					String allRoles = "";

+					if (idx < args.length) 

+						allRoles = args[idx++];

+						

+					rpr.setRole(allRoles);

+					frpr = client.update(

+							"/authz/role/perm", 

+							getDF(RolePermRequest.class), 

+							rpr);

+					if(frpr.get(AAFcli.timeout())) {

+						pw().println("Set Permission's Roles to [" + allRoles + "]");

+					} else {

+						error(frpr);

+					}			

+				} 

+				return frpr==null?0:frpr.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Grant a Permission to a Role or Roles  OR");

+		detailLine(sb,indent,"Ungrant a Permission from a Role or Roles  OR");

+		detailLine(sb,indent,"Set a Permission's roles to roles supplied.");

+		detailLine(sb,indent+4,"WARNING: Roles supplied with setTo will be the ONLY roles attached to this permission");

+		detailLine(sb,indent+8,"If no roles are supplied, permission's roles are reset.");

+		detailLine(sb,indent,"see Create for definitions of type,instance and action");

+		api(sb,indent,HttpMethods.POST,"authz/role/perm",RolePermRequest.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/role/<role>/perm",RolePermRequest.class,false);

+		api(sb,indent,HttpMethods.PUT,"authz/role/perm",RolePermRequest.class,false);

+

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/List.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/List.java
new file mode 100644
index 0000000..b29d6ee
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/List.java
@@ -0,0 +1,129 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Pkey;

+

+

+public class List extends BaseCmd<Perm> {

+//	private static final String LIST_PERM_DETAILS = "list permission details";

+	

+	public List(Perm parent) {

+		super(parent,"list");

+

+		cmds.add(new ListByUser(this));

+		cmds.add(new ListByName(this));

+		cmds.add(new ListByNS(this));

+		cmds.add(new ListByRole(this));

+		cmds.add(new ListActivity(this));

+	}

+	// Package Level on purpose

+	abstract class ListPerms extends Retryable<Integer> {

+		protected int list(Future<Perms> fp,Rcli<?> client, String header, String parentPerm) throws CadiException, APIException  {

+			if(fp.get(AAFcli.timeout())) {	

+				ArrayList<String> permNss = null;

+				if (aafcli.isDetailed()) {

+					permNss = new ArrayList<String>();

+					String permNs = null;

+					for(Pkey perm : fp.value.getPerm()) {	

+						if (permNs != null && perm.getType().contains(permNs)) {

+						    permNss.add(permNs);

+						} else {

+							Future<Nss> fpn = null;

+							String permType = perm.getType();

+							permNs = permType;

+							do {

+								permNs = permType.substring(0,permNs.lastIndexOf('.'));

+								fpn = client.read("/authz/nss/"+permNs,getDF(Nss.class));

+							} while (!fpn.get(AAFcli.timeout()));

+							permNss.add(permNs);

+						}

+					}						

+				} 

+				report(fp,permNss,header, parentPerm);

+			} else {

+				error(fp);

+			}

+			return fp.code();

+		}

+	}

+

+	private static final Comparator<aaf.v2_0.Perm> permCompare = new Comparator<aaf.v2_0.Perm>() {

+		@Override

+		public int compare(aaf.v2_0.Perm a, aaf.v2_0.Perm b) {

+			int rc;

+			if((rc=a.getType().compareTo(b.getType()))!=0) {

+			    return rc;

+			}

+			if((rc=a.getInstance().compareTo(b.getInstance()))!=0) {

+			    return rc;

+			}

+			return a.getAction().compareTo(b.getAction());

+		}

+	};

+	

+	void report(Future<Perms> fp, ArrayList<String> permNss, String ... str) {

+		reportHead(str);

+		if (this.aafcli.isDetailed()) {		

+			String format = reportColHead("%-20s %-15s %-30s %-15s\n   %-75s\n","PERM NS","Type","Instance","Action", "Description");

+			Collections.sort(fp.value.getPerm(),permCompare);

+			for(aaf.v2_0.Perm p : fp.value.getPerm()) {

+				String permNs = permNss.remove(0);

+				pw().format(format,

+					permNs,

+					p.getType().substring(permNs.length()+1),

+					p.getInstance(),

+					p.getAction(),

+					p.getDescription()==null?"":p.getDescription());

+			}

+			pw().println();

+		} else {

+			String format = reportColHead("%-30s %-30s %-10s\n","PERM Type","Instance","Action");

+

+			Collections.sort(fp.value.getPerm(),permCompare);

+			for(aaf.v2_0.Perm p : fp.value.getPerm()) {

+				pw().format(format,

+					p.getType(),

+					p.getInstance(),

+					p.getAction());

+			}

+			pw().println();

+		}

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListActivity.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListActivity.java
new file mode 100644
index 0000000..28709b4
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListActivity.java
@@ -0,0 +1,77 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.History;

+

+/**

+ *

+ */

+public class ListActivity extends Cmd {

+	private static final String HEADER = "List Activity of Permission";

+	

+	public ListActivity(List parent) {

+		super(parent,"activity", 

+				new Param("type",true));

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String type = args[idx++];

+				Future<History> fp = client.read(

+						"/authz/hist/perm/"+type, 

+						getDF(History.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					activity(fp.value, HEADER + " [ " + type + " ]");

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/hist/perm/<type>",History.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByNS.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByNS.java
new file mode 100644
index 0000000..24aa990
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByNS.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Perms;

+

+/**

+ * Return Perms by NS

+ * 

+ *

+ */

+public class ListByNS extends Cmd {

+	private static final String HEADER = "List Perms by NS ";

+	

+	public ListByNS(List parent) {

+		super(parent,"ns", 

+				new Param("name",true)); 

+	}

+

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final String ns=args[idx];

+

+		return same(((List)parent).new ListPerms() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Perms> fp = client.read(

+						"/authz/perms/ns/"+ns, 

+						getDF(Perms.class)

+						);

+				return list(fp,client, HEADER, ns);

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/perms/ns/<ns>",Perms.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByName.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByName.java
new file mode 100644
index 0000000..b2ae471
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByName.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Perms;

+

+/**

+ * 

+ *

+ */

+public class ListByName extends Cmd {

+	private static final String HEADER = "List Child Permissions";

+	

+	public ListByName(List parent) {

+		super(parent,"name", 

+				new Param("root perm name",true)); 

+	}

+

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(((List)parent).new ListPerms() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				String parentPerm=args[index];

+				

+				Future<Perms> fp = client.read(

+						"/authz/perms/"+parentPerm, 

+						getDF(Perms.class) 

+						);

+				return list(fp,client,HEADER,parentPerm);

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/perms/<parent type>",Perms.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByRole.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByRole.java
new file mode 100644
index 0000000..8f387c0
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByRole.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Perms;

+

+/**

+ * Return Perms by Role

+ * 

+ *

+ */

+public class ListByRole extends Cmd {

+	private static final String HEADER = "List Perms by Role ";

+	

+	public ListByRole(List parent) {

+		super(parent,"role", 

+				new Param("name",true)); 

+	}

+

+	public int _exec(final int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final String role=args[idx];

+

+		return same(((List)parent).new ListPerms() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+

+				Future<Perms> fp = client.read(

+						"/authz/perms/role/"+role, 

+						getDF(Perms.class)

+						);

+				return list(fp,client, HEADER, role);

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/perms/role/<role>",Perms.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByUser.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByUser.java
new file mode 100644
index 0000000..b08fb4e
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/ListByUser.java
@@ -0,0 +1,76 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Perms;

+

+/**

+ * 

+ *

+ */

+public class ListByUser extends Cmd {

+	private static final String HEADER = "List Permissions by User";

+	public ListByUser(List parent) {

+		super(parent,"user", 

+				new Param("id",true)); 

+	}

+

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		String user=args[idx];

+		String realm = getOrgRealm();

+		final String fullUser;

+		if (user.indexOf('@') < 0 && realm != null) 

+			fullUser = user + '@' + realm;

+		else

+			fullUser = user;

+		

+		return same(((List)parent).new ListPerms() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Perms> fp = client.read(

+						"/authz/perms/user/"+fullUser, 

+						getDF(Perms.class)

+						);

+				return list(fp, client, HEADER, fullUser);

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/perms/user/<user id>",Perms.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Perm.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Perm.java
new file mode 100644
index 0000000..5810998
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Perm.java
@@ -0,0 +1,44 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class Perm extends BaseCmd<Perm> {

+	Role role;

+

+	public Perm(Role role) throws APIException {

+		super(role.aafcli, "perm");

+		this.role = role;

+

+		cmds.add(new Create(this));

+		cmds.add(new Delete(this));

+		cmds.add(new Grant(this));

+		cmds.add(new Rename(this));

+		cmds.add(new Describe(this));

+		cmds.add(new List(this));

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Rename.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Rename.java
new file mode 100644
index 0000000..0198569
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/perm/Rename.java
@@ -0,0 +1,103 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.PermRequest;

+

+public class Rename extends Cmd {

+	public Rename(Perm parent) {

+		super(parent,"rename", 

+				new Param("type",true), 

+				new Param("instance",true),

+				new Param("action", true),

+				new Param("new type",true), 

+				new Param("new instance",true),

+				new Param("new action", true)

+				);

+	}

+	

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String origType = args[idx++];

+				String origInstance = args[idx++];

+				String origAction = args[idx++];

+				

+				//Create new permission

+				PermRequest pr = new PermRequest();

+				pr.setType(args[idx++]);

+				pr.setInstance(args[idx++]);

+				pr.setAction(args[idx++]);

+				

+				// Set Start/End commands

+				setStartEnd(pr);

+				Future<PermRequest> fp = client.update(

+						"/authz/perm/"+origType+"/"+origInstance+"/"+origAction,

+						getDF(PermRequest.class),

+						pr

+						);

+				int rv;

+				if(fp.get(AAFcli.timeout())) {

+					rv = fp.code();

+					pw().println("Updated Permission");

+				} else {

+					rv = fp.code();

+					if(rv==202) {

+						pw().println("Permission Update Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return rv;

+			}

+		});

+		

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Rename a Permission from:");

+		detailLine(sb,indent+2,"<type> <instance> <action>");

+		detailLine(sb,indent,"to:");

+		detailLine(sb,indent+2,"<new type> <new instance> <new action>");

+		sb.append('\n');

+		detailLine(sb,indent,"Namespace must be the same in <type> and <new type>");

+		detailLine(sb,indent+4,"see Create for definitions of type,instance and action");

+		api(sb,indent,HttpMethods.PUT,"authz/perm/<type>/<instance>/<action>",PermRequest.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/CreateDelete.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/CreateDelete.java
new file mode 100644
index 0000000..78ab181
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/CreateDelete.java
@@ -0,0 +1,132 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.RoleRequest;

+

+/**

+ * 

+ *

+ */

+public class CreateDelete extends Cmd {

+	private static final String ROLE_PATH = "/authz/role";

+	private final static String[] options = {"create","delete"};

+	public CreateDelete(Role parent) {

+		super(parent,null, 

+				new Param(optionsToString(options),true),

+				new Param("name",true)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String action = args[idx++];

+				int option = whichOption(options, action);

+		

+				RoleRequest rr = new RoleRequest();

+				rr.setName(args[idx++]);

+		

+				// Set Start/End commands

+				setStartEnd(rr);

+				

+				Future<RoleRequest> fp = null;

+				String verb = null;

+				int rv;

+				switch(option) {

+					case 0:

+						fp = client.create(

+							ROLE_PATH,

+							getDF(RoleRequest.class),

+							rr

+							);

+						verb = "Create";

+						break;

+					case 1:

+						// Send "Force" if set

+						setQueryParamsOn(client);

+						fp = client.delete(

+								ROLE_PATH, // +args[idx++], 

+								getDF(RoleRequest.class),

+								rr

+								);

+						verb = "Delete";

+						break;

+					default: // note, if not an option, whichOption throws Exception

+						break;

+						

+				}

+				boolean rolesSupplied = (args.length>idx);

+				if(fp.get(AAFcli.timeout())) {

+					rv=fp.code();

+					pw().print(verb);

+					pw().println("d Role");

+					if(rolesSupplied) {

+						for(;args.length>idx;++idx ) {

+							try {

+								if(201!=(rv=((Role)parent)._exec(0,new String[] {"user","add",rr.getName(),args[idx]}))) {

+									rv = HttpStatus.PARTIAL_CONTENT_206;

+								}

+							} catch (LocatorException e) {

+								throw new CadiException(e);

+							}

+						}

+					}

+				} else {

+					if((rv=fp.code())==202) {

+						pw().print("Role ");

+						pw().print(verb);

+						pw().println(" Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return rv;

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Create OR Delete a Role");

+		detailLine(sb,indent+2,"name - Name of Role to create");

+		api(sb,indent,HttpMethods.POST,"authz/role",RoleRequest.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/role",RoleRequest.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Describe.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Describe.java
new file mode 100644
index 0000000..d5fa19e
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Describe.java
@@ -0,0 +1,96 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.RoleRequest;

+

+public class Describe extends Cmd {

+	private static final String ROLE_PATH = "/authz/role";

+	public Describe(Role parent) {

+		super(parent,"describe", 

+				new Param("name",true),

+				new Param("description",true)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String role = args[idx++];

+				StringBuilder desc = new StringBuilder();

+				while (idx < args.length) {

+					desc.append(args[idx++] + ' ');

+				}

+		

+				RoleRequest rr = new RoleRequest();

+				rr.setName(role);

+				rr.setDescription(desc.toString());

+		

+				// Set Start/End commands

+				setStartEnd(rr);

+				

+				Future<RoleRequest> fp = null;

+				int rv;

+

+				fp = client.update(

+					ROLE_PATH,

+					getDF(RoleRequest.class),

+					rr

+					);

+

+				if(fp.get(AAFcli.timeout())) {

+					rv=fp.code();

+					pw().println("Description added to role");

+				} else {

+					if((rv=fp.code())==202) {

+						pw().print("Adding description");

+						pw().println(" Accepted, but requires Approvals before actualizing");

+					} else {

+						error(fp);

+					}

+				}

+				return rv;

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Add a description to a role");

+		api(sb,indent,HttpMethods.PUT,"authz/role",RoleRequest.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/List.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/List.java
new file mode 100644
index 0000000..33f9a99
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/List.java
@@ -0,0 +1,169 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.HashMap;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Pkey;

+import aaf.v2_0.Roles;

+

+

+

+public class List extends BaseCmd<Role> {

+	private static final String LIST_ROLES_BY_NAME = "list roles for role";

+

+	public List(Role parent) {

+		super(parent,"list");

+		cmds.add(new ListByUser(this));

+		cmds.add(new ListByRole(this));

+		cmds.add(new ListByNS(this));

+		cmds.add(new ListByNameOnly(this));

+		cmds.add(new ListByPerm(this));

+		cmds.add(new ListActivity(this));

+	}

+	

+	// Package Level on purpose

+	abstract class ListRoles extends Retryable<Integer> {

+		protected int list(Future<Roles> fp,Rcli<?> client, String header) throws APIException, CadiException {

+			if(fp.get(AAFcli.timeout())) {

+				Future<Nss> fn = null;

+				ArrayList<String> roleNss = null;

+				ArrayList<String> permNss = null;

+				if (aafcli.isDetailed()) {

+					roleNss = new ArrayList<String>();

+					permNss = new ArrayList<String>();

+					for(aaf.v2_0.Role p : fp.value.getRole()) {

+						String roleNs = p.getName();

+						do {

+							roleNs = p.getName().substring(0,roleNs.lastIndexOf('.'));

+							fn = client.read("/authz/nss/"+roleNs,getDF(Nss.class));

+						} while (!fn.get(AAFcli.timeout()));

+						roleNss.add(roleNs);

+		

+						for(Pkey perm : p.getPerms()) {

+							if (perm.getType().contains(roleNs))

+								permNss.add(roleNs);

+							else {

+								Future<Nss> fpn = null;

+								String permType = perm.getType();

+								String permNs = permType;

+								do {

+									permNs = permType.substring(0,permNs.lastIndexOf('.'));

+									fpn = client.read("/authz/nss/"+permNs,getDF(Nss.class));

+								} while (!fpn.get(AAFcli.timeout()));

+								permNss.add(permNs);

+							}

+						}

+					}

+				}

+				report(fp,roleNss,permNss,null,header);

+			} else {

+				error(fp);

+			}

+			return fp.code();

+		}

+	}

+

+	private final static String roleFormat = "%-50s\n";

+	

+	private static final Comparator<aaf.v2_0.Role> roleCompare = new Comparator<aaf.v2_0.Role>() {

+		@Override

+		public int compare(aaf.v2_0.Role a, aaf.v2_0.Role b) {

+			return a.getName().compareTo(b.getName());

+		}

+	};

+	public void report(Future<Roles> fp, ArrayList<String> roleNss, ArrayList<String> permNss,

+			HashMap<String,Boolean> expiredMap, String ... str) {

+		reportHead(str);

+		if (fp != null && aafcli.isDetailed() && str[0].toLowerCase().contains(LIST_ROLES_BY_NAME)) {

+			String description = fp.value.getRole().get(0).getDescription();

+			if (description == null) description = "";

+			reportColHead("%-80s\n","Description: " + description);

+		} 			

+

+		if(fp==null) {

+			pw().println("<No Roles Found>");

+		} else if (aafcli.isDetailed()){

+			String permFormat = "   %-20s %-15s %-30s %-15s\n";

+			String fullFormat = roleFormat+permFormat;

+			reportColHead(fullFormat,"[ROLE NS].Name","PERM NS","Type","Instance","Action");

+			Collections.sort(fp.value.getRole(),roleCompare);

+			for(aaf.v2_0.Role p : fp.value.getRole()) {

+				String roleNs = roleNss.remove(0);

+				pw().format(roleFormat, "["+roleNs+"]"+p.getName().substring(roleNs.length()));

+				for(Pkey perm : p.getPerms()) {

+					String permNs = permNss.remove(0);

+					pw().format(permFormat, 

+							permNs,

+							perm.getType().substring(permNs.length()+1),

+							perm.getInstance(),

+							perm.getAction());

+				}

+			}

+		} else {

+			String permFormat = "   %-30s %-30s %-15s\n";

+			String fullFormat = roleFormat+permFormat;

+			reportColHead(fullFormat,"ROLE Name","PERM Type","Instance","Action");

+			Collections.sort(fp.value.getRole(),roleCompare);

+			for(aaf.v2_0.Role p : fp.value.getRole()) {

+				if (expiredMap != null) {

+					String roleName = p.getName();

+					Boolean b = expiredMap.get(roleName);

+					if (b != null && b.booleanValue())

+						pw().format(roleFormat, roleName+"*");

+					else {

+						pw().format(roleFormat, roleName);

+						for(Pkey perm : p.getPerms()) {

+							pw().format(permFormat, 

+									perm.getType(),

+									perm.getInstance(),

+									perm.getAction());

+						}

+					}

+				} else {

+					pw().format(roleFormat, p.getName());

+					for(Pkey perm : p.getPerms()) {

+						pw().format(permFormat, 

+								perm.getType(),

+								perm.getInstance(),

+								perm.getAction());

+					}

+				}

+			}

+		}

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListActivity.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListActivity.java
new file mode 100644
index 0000000..780bb48
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListActivity.java
@@ -0,0 +1,76 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.History;

+

+/**

+ *

+ */

+public class ListActivity extends Cmd {

+	private static final String HEADER = "List Activity of Role";

+

+	public ListActivity(List parent) {

+		super(parent,"activity", 

+				new Param("name",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String role = args[idx++];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<History> fp = client.read(

+						"/authz/hist/role/"+role, 

+						getDF(History.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					activity(fp.value,HEADER + " [ " + role + " ]");

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/hist/role/<role>",History.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNS.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNS.java
new file mode 100644
index 0000000..35ef634
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNS.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Roles;

+

+/**

+ * Return Roles by NS

+ * 

+ *

+ */

+public class ListByNS extends Cmd {

+	private static final String HEADER = "List Roles by NS ";

+	

+	public ListByNS(List parent) {

+		super(parent,"ns", 

+				new Param("name",true)); 

+	}

+

+	@Override

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final String ns=args[idx];

+

+		return same(((List)parent).new ListRoles() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Roles> fp = client.read(

+						"/authz/roles/ns/"+ns, 

+						getDF(Roles.class)

+						);

+				return list(fp,client, HEADER+"["+ns+"]");

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/roles/name/<ns>",Roles.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNameOnly.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNameOnly.java
new file mode 100644
index 0000000..5db02e4
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByNameOnly.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Roles;

+

+/**

+ * Return Roles by NS

+ * 

+ *

+ */

+public class ListByNameOnly extends Cmd {

+	private static final String HEADER = "List Roles by Name ";

+	

+	public ListByNameOnly(List parent) {

+		super(parent,"name", 

+				new Param("name",true)); 

+	}

+

+	@Override

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		final String name=args[idx];

+

+		return same(((List)parent).new ListRoles() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Roles> fp = client.read(

+						"/authz/roles/name/"+name, 

+						getDF(Roles.class)

+						);

+				return list(fp,client, HEADER+"["+name+"]");

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/roles/name/<name>",Roles.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByPerm.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByPerm.java
new file mode 100644
index 0000000..4fcdca9
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByPerm.java
@@ -0,0 +1,79 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Roles;

+

+/**

+ * Return Roles by NS

+ * 

+ *

+ */

+public class ListByPerm extends Cmd {

+	private static final String HEADER = "List Roles by Perm ";

+	

+	public ListByPerm(List parent) {

+		super(parent,"perm", 

+				new Param("type",true),

+				new Param("instance", true),

+				new Param("action", true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String type=args[idx];

+		final String instance=args[++idx];

+		final String action=args[++idx];

+

+		return same(((List)parent).new ListRoles() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+

+				Future<Roles> fp = client.read(

+						"/authz/roles/perm/"+type+'/'+instance+'/'+action, 

+						getDF(Roles.class)

+						);

+				return list(fp,client, HEADER+type+'|'+instance+'|'+action);

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/roles/user/<user>",Roles.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByRole.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByRole.java
new file mode 100644
index 0000000..f4db514
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByRole.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Roles;

+

+/**

+ * 

+ *

+ */

+public class ListByRole extends Cmd {

+	private static final String HEADER="List Roles for Role";

+	

+	public ListByRole(List parent) {

+		super(parent,"role", 

+				new Param("role",true)); 

+	}

+

+	@Override

+	public int _exec(final int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(((List)parent).new ListRoles() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				String role=args[idx];	

+				Future<Roles> fp = client.read(

+						"/authz/roles/"+role, 

+						getDF(Roles.class) 

+						);

+				return list(fp,client,HEADER+"["+role+"]");

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/roles/<role>",Roles.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByUser.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByUser.java
new file mode 100644
index 0000000..b333dec
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/ListByUser.java
@@ -0,0 +1,146 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Chrono;

+

+import aaf.v2_0.Nss;

+import aaf.v2_0.Pkey;

+import aaf.v2_0.Roles;

+import aaf.v2_0.Users;

+

+/**

+ * p

+ *

+ */

+public class ListByUser extends Cmd {

+	private static final String HEADER = "List Roles for User ";

+	

+	public ListByUser(List parent) {

+		super(parent,"user", 

+				new Param("id",true)); 

+	}

+

+	@Override

+	public int _exec( int idx, final String ... args) throws CadiException, APIException, LocatorException {

+		String user=args[idx];

+		String realm = getOrgRealm();

+		final String fullUser;

+		if (user.indexOf('@') < 0 && realm != null) {

+		    fullUser = user + '@' + realm;

+		} else {

+		    fullUser = user;

+		}

+

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+

+				Future<Roles> fp = client.read(

+						"/authz/roles/user/"+fullUser, 

+						getDF(Roles.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					Future<Nss> fn = null;

+					ArrayList<String> roleNss = null;

+					ArrayList<String> permNss = null;

+					HashMap<String, Boolean> expiredMap = new HashMap<String, Boolean>();

+					if (aafcli.isDetailed()) {

+						roleNss = new ArrayList<String>();

+						permNss = new ArrayList<String>();

+						for(aaf.v2_0.Role p : fp.value.getRole()) {

+							String roleNs = p.getName();

+							do {

+								roleNs = p.getName().substring(0,roleNs.lastIndexOf('.'));

+								fn = client.read("/authz/nss/"+roleNs,getDF(Nss.class));

+							} while (!fn.get(AAFcli.timeout()));

+							roleNss.add(roleNs);

+	

+							for(Pkey perm : p.getPerms()) {

+								if (perm.getType().contains(roleNs)) {

+								    permNss.add(roleNs);

+								} else {

+									Future<Nss> fpn = null;

+									String permType = perm.getType();

+									String permNs = permType;

+									do {

+										permNs = permType.substring(0,permNs.lastIndexOf('.'));

+										fpn = client.read("/authz/nss/"+permNs,getDF(Nss.class));

+									} while (!fpn.get(AAFcli.timeout()));

+									permNss.add(permNs);

+								}

+							}

+						}

+					}

+					

+					if (fp.value != null) {

+						for(aaf.v2_0.Role p : fp.value.getRole()) {

+							Future<Users> fu = client.read(

+									"/authz/userRole/"+fullUser+"/"+p.getName(), 

+									getDF(Users.class)

+									);

+							if (fu.get(5000)) {

+								if(fu.value != null) {

+								    for (Users.User u : fu.value.getUser()) {

+								    	if(u.getExpires().normalize().compare(Chrono.timeStamp().normalize()) > 0) {

+								    		expiredMap.put(p.getName(), new Boolean(false));

+								    	} else {

+								    		expiredMap.put(p.getName(), new Boolean(true));

+								    	}

+								    }

+								}

+							}

+						}	

+					}

+					

+					((List)parent).report(fp,roleNss,permNss,expiredMap,HEADER,fullUser);

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/roles/user/<user>",Roles.class,true);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Role.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Role.java
new file mode 100644
index 0000000..4b5c225
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/Role.java
@@ -0,0 +1,41 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class Role extends BaseCmd<Role> {

+	public List list;

+

+	public Role(AAFcli aafcli) throws APIException {

+		super(aafcli, "role");

+		cmds.add(new CreateDelete(this));

+//		cmds.add(new Delete(this));

+		cmds.add(new User(this));

+		cmds.add(new Describe(this));

+		cmds.add(list = new List(this));

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/role/User.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/User.java
new file mode 100644
index 0000000..239ab84
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/role/User.java
@@ -0,0 +1,171 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.UserRoleRequest;

+

+/**

+ * p

+ *

+ */

+public class User extends Cmd {

+	private final static String[] options = {"add","del","setTo","extend"};

+	public User(Role parent) {

+		super(parent,"user", 

+				new Param(optionsToString(options),true),

+				new Param("role",true),

+				new Param("id[,id]* (not required for setTo)",false)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String realm = getOrgRealm();

+				String action = args[idx++];

+				int option = whichOption(options, action);

+				UserRoleRequest urr = new UserRoleRequest();

+				urr.setRole(args[idx++]);

+				// Set Start/End commands

+				setStartEnd(urr);

+				

+				Future<?> fp = null;

+				

+				if (option != 2) {

+					String[] ids = args[idx++].split(",");

+					String verb=null,participle=null;

+					// You can request to be added or removed from role.

+					setQueryParamsOn(client);

+

+					for(String id: ids) {

+						if (id.indexOf('@') < 0 && realm != null) id += '@' + realm;

+						urr.setUser(id);

+						switch(option) {

+							case 0:

+								fp = client.create(

+										"/authz/userRole", 

+										getDF(UserRoleRequest.class), 

+										urr);

+								verb = "Added";

+								participle = "] to Role [" ;

+								break;

+							case 1:

+								fp = client.delete(

+										"/authz/userRole/"+urr.getUser()+'/'+urr.getRole(), 

+										Void.class);

+								verb = "Removed";

+								participle = "] from Role [" ;

+								break;

+						    case 3:

+								fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole());

+								verb = "Extended";

+								participle = "] in Role [" ;

+								break;

+

+							default: // actually, should never get here...

+								throw new CadiException("Invalid action [" + action + ']');

+						}

+						if(fp.get(AAFcli.timeout())) {

+							pw().print(verb);

+							pw().print(" User [");

+							pw().print(urr.getUser());

+							pw().print(participle);

+							pw().print(urr.getRole());

+							pw().println(']');

+						} else {

+							switch(fp.code()) {

+								case 202:

+									pw().print("User Role ");

+									pw().print(action);

+									pw().println(" is Accepted, but requires Approvals before actualizing");

+									break;

+								case 404:

+									if(option==3) {

+										pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view");

+										break;

+									}

+								default:

+									error(fp);

+							}

+						}

+					}

+				} else {

+					String allUsers = "";

+					if (idx < args.length) 

+						allUsers = args[idx++];

+					StringBuilder finalUsers = new StringBuilder();	

+					for (String u : allUsers.split(",")) {

+						if (u != "") {

+							if (u.indexOf('@') < 0 && realm != null) u += '@' + realm;

+							if (finalUsers.length() > 0) finalUsers.append(",");

+							finalUsers.append(u);

+						}

+					}

+

+					urr.setUser(finalUsers.toString());

+					fp = client.update(

+							"/authz/userRole/role", 

+							getDF(UserRoleRequest.class), 

+							urr);

+					if(fp.get(AAFcli.timeout())) {

+						pw().println("Set the Role to Users [" + allUsers + "]");

+					} else {

+						error(fp);

+					}		

+				}

+				return fp==null?0:fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,"Add OR Delete a User to/from a Role OR");

+		detailLine(sb,indent,"Set a User's Roles to the roles supplied");

+		detailLine(sb,indent+2,"role  - Name of Role to create");

+		detailLine(sb,indent+2,"id(s) - ID or IDs to add to the Role");

+		sb.append('\n');

+		detailLine(sb,indent+2,"Note: this is the same as \"user role add...\" except allows");

+		detailLine(sb,indent+2,"assignment of role to multiple userss");

+		detailLine(sb,indent+2,"WARNING: Users supplied with setTo will be the ONLY users attached to this role");

+		detailLine(sb,indent+2,"If no users are supplied, the users attached to this role are reset.");

+		api(sb,indent,HttpMethods.POST,"authz/userRole",UserRoleRequest.class,true);

+		api(sb,indent,HttpMethods.DELETE,"authz/userRole/<user>/<role>",Void.class,false);

+		api(sb,indent,HttpMethods.PUT,"authz/userRole/<role>",UserRoleRequest.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Cred.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Cred.java
new file mode 100644
index 0000000..b6fd83f
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Cred.java
@@ -0,0 +1,153 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.CredRequest;

+

+public class Cred extends Cmd {

+		private static final String CRED_PATH = "/authn/cred";

+		private static final String[] options = {"add","del","reset","extend"/*,"clean"*/};

+//		private Clean clean;

+		public Cred(User parent) {

+			super(parent,"cred",

+					new Param(optionsToString(options),true),

+					new Param("id",true),

+					new Param("password (! D|E)",false),

+					new Param("entry# (if multi)",false)

+			);

+//			clean = new Clean(this);

+		}

+

+		@Override

+		public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException { 

+		    int idx = _idx;

+			String key = args[idx++];

+			final int option = whichOption(options,key);

+

+			final CredRequest cr = new CredRequest();

+			cr.setId(args[idx++]);

+			if(option!=1 && option!=3) {

+				if(idx>=args.length) throw new CadiException("Password Required");

+				cr.setPassword(args[idx++]);

+			}

+			if(args.length>idx)

+				cr.setEntry(args[idx++]);

+			

+			// Set Start/End commands

+			setStartEnd(cr);

+//			final int cleanIDX = _idx+1;

+			Integer ret = same(new Retryable<Integer>() {

+				@Override

+				public Integer code(Rcli<?> client) throws CadiException, APIException {

+					Future<CredRequest> fp=null;

+					String verb =null;

+					switch(option) {

+						case 0:

+							fp = client.create(

+								CRED_PATH, 

+								getDF(CredRequest.class), 

+								cr

+								);

+							verb = "Added Credential [";

+							break;

+						case 1:

+//							if(aafcli.addForce())cr.setForce("TRUE");

+							setQueryParamsOn(client);

+							fp = client.delete(CRED_PATH,

+								getDF(CredRequest.class),

+								cr

+								);

+							verb = "Deleted Credential [";

+							break;

+						case 2:

+							fp = client.update(

+								CRED_PATH,

+								getDF(CredRequest.class),

+								cr

+								);

+							verb = "Reset Credential [";

+							break;

+						case 3:

+							fp = client.update(

+								CRED_PATH+"/5",

+								getDF(CredRequest.class),

+								cr

+								);

+							verb = "Extended Credential [";

+							break;

+//						case 4:

+//							return clean.exec(cleanIDX, args);

+					}

+					if(fp.get(AAFcli.timeout())) {

+						pw().print(verb);

+						pw().print(cr.getId());

+						pw().println(']');

+					} else if(fp.code()==202) {

+							pw().println("Credential Action Accepted, but requires Approvals before actualizing");

+					} else if(fp.code()==406 && option==1) {

+							pw().println("You cannot delete this Credential");

+					} else {

+						error(fp);

+					}

+					return fp.code();

+				}

+			});

+			if(ret==null)ret = -1;

+			return ret;

+		}

+		

+		@Override

+		public void detailedHelp(int _indent, StringBuilder sb) {

+		        int indent = _indent;

+			detailLine(sb,indent,"Add, Delete or Reset Credential");

+			indent+=2;

+			detailLine(sb,indent,"id       - the ID to create/delete/reset within AAF");

+			detailLine(sb,indent,"password - Company Policy compliant Password (not required for Delete)");

+			detailLine(sb,indent,"entry    - selected option when deleting/resetting a cred with multiple entries");

+			sb.append('\n');

+			detailLine(sb,indent,"The Domain can be related to any Namespace you have access to *");

+			detailLine(sb,indent,"The Domain is in reverse order of Namespace, i.e. ");

+			detailLine(sb,indent+2,"NS of com.att.myapp can create user of XY1234@myapp.att.com");

+			sb.append('\n');

+			detailLine(sb,indent,"NOTE: AAF does support multiple creds with the same ID. Check with your org if you");

+			detailLine(sb,indent+2,"have this implemented. (For example, this is implemented for MechIDs at AT&T)");

+			sb.append('\n');			

+			detailLine(sb,indent,"Delegates can be listed by the User or by the Delegate");

+			indent-=2;

+			api(sb,indent,HttpMethods.POST,"authn/cred",CredRequest.class,true);

+			api(sb,indent,HttpMethods.DELETE,"authn/cred",CredRequest.class,false);

+			api(sb,indent,HttpMethods.PUT,"authn/cred",CredRequest.class,false);

+		}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Delg.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Delg.java
new file mode 100644
index 0000000..edb5c38
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Delg.java
@@ -0,0 +1,136 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import java.text.ParseException;

+import java.util.Date;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.util.Chrono;

+import org.onap.aaf.rosetta.env.RosettaDF;

+

+import aaf.v2_0.DelgRequest;

+

+public class Delg extends BaseCmd<User> {

+	static final String AUTHZ_DELG = "/authz/delegate";

+	private final static String[] options = {"add","upd","del"};

+

+	public Delg(User user) throws APIException {

+		super(user,"delegate",

+				new Param(optionsToString(options),true),

+				new Param("from",true),

+				new Param("to REQ A&U",false),

+				new Param("until (YYYY-MM-DD) REQ A", false)

+		);

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String realm = getOrgRealm();

+				DelgRequest dr = new DelgRequest();

+				setStartEnd(dr);

+		

+				int option= whichOption(options, args[idx++]);

+				String user = args[idx++];

+				if (user.indexOf('@') < 0 && realm != null) user += '@' + realm;

+				dr.setUser(user);

+				if(option<2) {

+					String delegate = args[idx++];

+					if (delegate.indexOf('@') < 0 && realm != null) delegate += '@' + realm;

+					dr.setDelegate(delegate);

+					if(option<2 && args.length>idx) {

+						Date date;

+						try {

+							date = Chrono.dateOnlyFmt.parse(args[idx++]);

+						} catch (ParseException e) {

+							throw new CadiException(e);

+						}

+						dr.setEnd(Chrono.timeStamp(date));

+					}

+				}

+		

+				Future<DelgRequest> fp;

+				RosettaDF<DelgRequest> df = getDF(DelgRequest.class);

+				String verb;

+				setQueryParamsOn(client);

+

+				switch(option) {

+					case 0: 

+						fp = client.create(AUTHZ_DELG, df, dr);

+						verb = "Added";

+						break;

+					case 1: 

+						fp = client.update(AUTHZ_DELG, df, dr); 

+						verb = "Updated";

+						break;

+					case 2: 

+						fp = client.delete(AUTHZ_DELG, df, dr); 

+						verb = "Deleted";

+						break;

+					default:

+						throw new CadiException("Bad Argument");

+				};

+				

+				if(fp.get(AAFcli.timeout())) {

+					pw().append("Delegate ");

+					pw().println(verb);

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,"Add, Update or Delete Delegate");

+		indent+=2;

+		detailLine(sb,indent,"A Delegate is a person who will temporarily cover the Approval and");

+		detailLine(sb,indent,"Ownership questions on behalf of the person Responsible.");

+		sb.append('\n');

+		detailLine(sb,indent,"fromID - the person who is the Responsible person of record");

+		detailLine(sb,indent,"toID   - the person who will be delegated (required for Add/Update)");

+		detailLine(sb,indent,"until  - the end date for this delegation");

+		indent-=2;

+		api(sb,indent,HttpMethods.POST,AUTHZ_DELG,DelgRequest.class,true);

+		api(sb,indent,HttpMethods.DELETE,AUTHZ_DELG,DelgRequest.class,false);

+		api(sb,indent,HttpMethods.PUT,AUTHZ_DELG,DelgRequest.class,false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/List.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/List.java
new file mode 100644
index 0000000..61779be
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/List.java
@@ -0,0 +1,122 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.util.Chrono;

+

+import aaf.v2_0.Approval;

+import aaf.v2_0.Approvals;

+import aaf.v2_0.Delg;

+import aaf.v2_0.Delgs;

+import aaf.v2_0.Users;

+

+public class List extends BaseCmd<User> {

+

+	public List(User parent) {

+		super(parent,"list");

+		cmds.add(new ListForRoles(this));

+		cmds.add(new ListForPermission(this));

+		cmds.add(new ListForCreds(this));

+		cmds.add(new ListDelegates(this));

+		cmds.add(new ListApprovals(this));

+		cmds.add(new ListActivity(this));

+	}

+

+	 

+	void report(Users users, boolean count, String ... str) {

+		reportHead(str);

+		String format = reportColHead("%-50s %-30s\n","User","Expires");

+		String date = "XXXX-XX-XX";

+		int idx = 0;

+		java.util.List<aaf.v2_0.Users.User> sorted = users.getUser();

+		Collections.sort(sorted, new Comparator<aaf.v2_0.Users.User>() {

+			@Override

+			public int compare(aaf.v2_0.Users.User u1, aaf.v2_0.Users.User u2) {

+				if(u2==null || u2 == null) {

+					return -1;

+				}

+				return u1.getId().compareTo(u2.getId());

+			}

+		});

+		for(aaf.v2_0.Users.User user : sorted) {

+			if(!aafcli.isTest()) 

+				date = Chrono.dateOnlyStamp(user.getExpires());

+			

+			pw().format(format, 

+					count? (Integer.valueOf(++idx) + ") " + user.getId()): user.getId(), 

+					date);

+		}

+		pw().println();

+	}

+

+	public void report(Approvals approvals, String title, String id) {

+		reportHead(title,id);

+		String format = reportColHead("  %-20s %-20s %-11s %-6s %12s\n","User","Approver","Type","Status","Updated");

+		java.util.List<Approval> lapp = approvals.getApprovals();

+		Collections.sort(lapp, new Comparator<Approval>() {

+			@Override

+			public int compare(Approval a1, Approval a2) {

+				return a1.getTicket().compareTo(a2.getTicket());

+			}

+		} );

+		String ticket = null, prev = null;

+		for(Approval app : lapp ) {

+			ticket = app.getTicket();

+			if(!ticket.equals(prev)) {

+				pw().print("Ticket: ");

+				pw().println(ticket);

+			}

+			prev = ticket;

+

+			pw().format(format,

+					app.getUser(),

+					app.getApprover(),

+					app.getType(),

+					app.getStatus(),

+					Chrono.niceDateStamp(app.getUpdated())

+					);

+		}

+	}

+

+	public void report(Delgs delgs, String title, String id) {

+		reportHead(title,id);

+		String format = reportColHead(" %-25s %-25s  %-10s\n","User","Delegate","Expires");

+		String date = "XXXX-XX-XX";

+		for(Delg delg : delgs.getDelgs()) {

+			if(!this.aafcli.isTest()) 

+				date = Chrono.dateOnlyStamp(delg.getExpires());

+			pw().printf(format, 

+						delg.getUser(),

+						delg.getDelegate(),

+						date

+						);

+		}

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListActivity.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListActivity.java
new file mode 100644
index 0000000..d8ce474
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListActivity.java
@@ -0,0 +1,81 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.History;

+

+/**

+ *

+ */

+public class ListActivity extends Cmd {

+	private static final String HEADER = "List Activity of User";

+

+	public ListActivity(List parent) {

+		super(parent,"activity", 

+				new Param("user",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		String user = args[idx++];

+		String realm = getOrgRealm();

+		final String fullUser = (user.indexOf('@') < 0 && realm != null)?user + '@' + realm:user;

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+		

+				Future<History> fp = client.read(

+						"/authz/hist/user/"+fullUser, 

+						getDF(History.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					activity(fp.value,HEADER + " [ " + fullUser + " ]");

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb,indent,HEADER);

+		api(sb,indent,HttpMethods.GET,"authz/hist/user/<user>",History.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListApprovals.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListApprovals.java
new file mode 100644
index 0000000..e478d20
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListApprovals.java
@@ -0,0 +1,104 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Approvals;

+

+/**

+ * 

+ *

+ */

+public class ListApprovals extends Cmd {

+	private static final String HEADER = "List Approvals"; 

+	private final static String[] options = {"user","approver","ticket"};

+	public ListApprovals(List parent) {

+		super(parent,"approvals", 

+				new Param(optionsToString(options),true),

+				new Param("value",true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String type = args[idx++];

+		int option = whichOption(options,type);

+		String value = args[idx++];

+		final String fullValue;

+		if (option != 2) {

+			String realm = getOrgRealm();

+			fullValue = (value.indexOf('@')<0 && realm != null)?value +'@'+realm:value;

+		} else {

+		    fullValue = value;

+		}

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Approvals> fp = client.read(

+						"/authz/approval/"+type+'/'+fullValue, 

+						getDF(Approvals.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					((List)parent).report(fp.value,HEADER + " by " + type,fullValue);

+					if(fp.code()==404) {

+					    return 200;

+					}

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=2;

+		detailLine(sb,indent,"Approvals are used when the Requestor does not have the rights");

+		detailLine(sb,indent,"to perform the action required.  Approvers are those listed as");

+		detailLine(sb,indent,"responsible for Namespace associated with the request, and those");

+		detailLine(sb,indent,"required by the Company by Policy.  This may be, for instance");

+		detailLine(sb,indent,"the supervisor of the requestor");

+		sb.append('\n');

+		detailLine(sb,indent,"Delegates can be listed by User, Approver or Ticket.");

+		indent-=2;

+		api(sb,indent,HttpMethods.GET,"authz/approval/user/<value>",Approvals.class,true);

+		api(sb,indent,HttpMethods.GET,"authz/approval/approver/<value>",Approvals.class,false);

+		api(sb,indent,HttpMethods.GET,"authz/approval/ticket/<value>",Approvals.class,false);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListDelegates.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListDelegates.java
new file mode 100644
index 0000000..723e302
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListDelegates.java
@@ -0,0 +1,95 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Delgs;

+

+/**

+ *

+ */

+public class ListDelegates extends Cmd {

+	private static final String HEADER = "List Delegates"; 

+	private static final String[] options = {"user","delegate"};

+	public ListDelegates(List parent) {

+		super(parent,"delegates", 

+				new Param(optionsToString(options),true),

+				new Param("id",true));

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+		String realm = getOrgRealm();

+		int idx = _idx;

+ 		final String key = args[idx++];

+		//int option = whichOption(options,key);

+		String id = args[idx++];

+		final String fullID = (id.indexOf('@') < 0 && realm != null)? id + '@' + realm:id;

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+		

+				Future<Delgs> fp = client.read(

+						"/authz/delegates/" + key + '/' + fullID, 

+						getDF(Delgs.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					((List)parent).report(fp.value,HEADER + " by " + key, fullID);

+					if(fp.code()==404)return 200;

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=2;

+		detailLine(sb,indent,"Delegates are those people temporarily assigned to cover the");

+		detailLine(sb,indent,"responsibility of Approving, etc, while the actual Responsible");

+		detailLine(sb,indent,"Party is absent.  Typically, this is for Vacation, or Business");

+		detailLine(sb,indent,"Travel.");

+		sb.append('\n');

+		detailLine(sb,indent,"Delegates can be listed by the User or by the Delegate");

+		indent-=2;

+		api(sb,indent,HttpMethods.GET,"authz/delegates/user/<id>",Delgs.class,true);

+		api(sb,indent,HttpMethods.GET,"authz/delegates/delegate/<id>",Delgs.class,false);

+	}

+

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForCreds.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForCreds.java
new file mode 100644
index 0000000..ec76e17
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForCreds.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+/**

+ * List for Creds

+ *

+ */

+public class ListForCreds extends Cmd {

+	private final static String[] options = {"ns","id"};

+

+	private static final String HEADER = "List creds for ";

+	public ListForCreds(List parent) {

+		super(parent,"cred",

+				new Param(optionsToString(options),true),

+				new Param("value",true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final int option = whichOption(options, args[idx++]);

+		final String which = options[option];

+		final String value = args[idx++];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Users> fp = client.read(

+						"/authn/creds/"+which+'/'+value, 

+						getDF(Users.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					if (aafcli.isTest())

+						Collections.sort(fp.value.getUser(), new Comparator<User>() {

+							@Override

+							public int compare(User u1, User u2) {

+								return u1.getId().compareTo(u2.getId());

+							}			

+						});

+					((org.onap.aaf.cmd.user.List)parent).report(fp.value,option==1,HEADER+which,value);

+					if(fp.code()==404)return 200;

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=2;

+		detailLine(sb,indent,"This report lists the users associated to Roles.");

+		detailLine(sb,indent,"role - the Role name");

+		indent-=2;

+		api(sb,indent,HttpMethods.GET,"authz/users/role/<role>",Users.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForPermission.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForPermission.java
new file mode 100644
index 0000000..c433610
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForPermission.java
@@ -0,0 +1,104 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+/**

+ * p

+ *

+ */

+public class ListForPermission extends Cmd {

+	private static final String HEADER = "List Users for Permission";

+	public ListForPermission(List parent) {

+		super(parent,"perm", 

+				new Param("type",true),

+				new Param("instance",true),

+				new Param("action",true)); 

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String type = args[idx++];

+				String instance = args[idx++];

+				if("\\*".equals(instance))instance="*";

+				String action = args[idx++];

+				if("\\*".equals(action))action="*";

+				Future<Users> fp = client.read(

+						"/authz/users/perm/"+type+'/'+instance+'/'+action, 

+						getDF(Users.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					if (aafcli.isTest())

+						Collections.sort(fp.value.getUser(), new Comparator<User>() {

+							@Override

+							public int compare(User u1, User u2) {

+								return u1.getId().compareTo(u2.getId());

+							}			

+						});

+					((org.onap.aaf.cmd.user.List)parent).report(fp.value,false,HEADER,type+"|"+instance+"|"+action);

+					if(fp.code()==404)return 200;

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=2;

+		detailLine(sb,indent,"This report lists the users associated to Permissions.  Since Users");

+		detailLine(sb,indent,"are associated to Roles, and Roles have Permissions, this report");

+		detailLine(sb,indent,"accomodates all these linkages.");

+		sb.append('\n');

+		detailLine(sb,indent,"The URL must contain the Permission's type,instance and action, and ");

+		detailLine(sb,indent,"may include \"*\"s (type in as \\\\*).");

+		detailLine(sb,indent,"See Perm Create Documentation for definitions.");

+		indent-=2;

+		api(sb,indent,HttpMethods.GET,"authz/users/perm/<type>/<instance>/<action>",Users.class,true);

+	}

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForRoles.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForRoles.java
new file mode 100644
index 0000000..528a33b
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/ListForRoles.java
@@ -0,0 +1,93 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import java.util.Collections;

+import java.util.Comparator;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+/**

+ * p

+ *

+ */

+public class ListForRoles extends Cmd {

+	private static final String HEADER = "List Users for Role";

+	public ListForRoles(List parent) {

+		super(parent,"role", new Param("role",true)); 

+	}

+

+	@Override

+	public int _exec(int _idx, final String ... args) throws CadiException, APIException, LocatorException {

+	        int idx = _idx;

+		final String role = args[idx++];

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				Future<Users> fp = client.read(

+						"/authz/users/role/"+role, 

+						getDF(Users.class)

+						);

+				if(fp.get(AAFcli.timeout())) {

+					if (aafcli.isTest())

+						Collections.sort(fp.value.getUser(), new Comparator<User>() {

+							@Override

+							public int compare(User u1, User u2) {

+								return u1.getId().compareTo(u2.getId());

+							}			

+						});

+					((org.onap.aaf.cmd.user.List)parent).report(fp.value,false, HEADER,role);

+					if(fp.code()==404)return 200;

+				} else {

+					error(fp);

+				}

+				return fp.code();

+			}

+		});

+	}

+	

+	@Override

+	public void detailedHelp(int _indent, StringBuilder sb) {

+	        int indent = _indent;

+		detailLine(sb,indent,HEADER);

+		indent+=2;

+		detailLine(sb,indent,"This report lists the users associated to Roles.");

+		detailLine(sb,indent,"role - the Role name");

+		indent-=2;

+		api(sb,indent,HttpMethods.GET,"authz/users/role/<role>",Users.class,true);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Role.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Role.java
new file mode 100644
index 0000000..bf7baaf
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/Role.java
@@ -0,0 +1,158 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Param;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.inno.env.APIException;

+

+import aaf.v2_0.UserRoleRequest;

+

+/**

+ * p

+ * 

+ *

+ */

+public class Role extends Cmd {

+	private static final String[] options = {"add", "del", "setTo","extend"};

+	public Role(User parent) {

+		super(parent, "role", new Param(optionsToString(options), true), new Param("user", true), new Param(

+				"role[,role]* (!REQ S)", false));

+	}

+

+	@Override

+	public int _exec(final int index, final String ... args) throws CadiException, APIException, LocatorException {

+		return same(new Retryable<Integer>() {

+			@Override

+			public Integer code(Rcli<?> client) throws CadiException, APIException {

+				int idx = index;

+				String key = args[idx++];

+				int option = whichOption(options, key);

+				String user = args[idx++];

+				String realm = getOrgRealm();

+

+				UserRoleRequest urr = new UserRoleRequest();

+				if (user.indexOf('@') < 0 && realm != null) user += '@' + realm;

+				urr.setUser(user);

+				// Set Start/End commands

+				setStartEnd(urr);

+

+				Future<?> fp = null;

+

+				if (option != 2) {

+					if (args.length < 5) {

+						throw new CadiException(build(new StringBuilder("Too few args: "), null).toString());                        

+					}

+					String[] roles = args[idx++].split(",");

+					for (String role : roles) {

+						String verb = null,participle=null;

+						urr.setRole(role);

+						// You can request to be added or removed from role.

+						setQueryParamsOn(client);

+						switch(option) {

+						  case 0:

+							fp = client.create("/authz/userRole", getDF(UserRoleRequest.class), urr);

+							verb = "Added";

+							participle = "] to User [" ;

+							break;

+						  case 1:

+							fp = client.delete("/authz/userRole/" + urr.getUser() + '/' + urr.getRole(), Void.class);

+							verb = "Removed";

+							participle = "] from User [" ;

+							break;

+						  case 3:

+							fp = client.update("/authz/userRole/extend/" + urr.getUser() + '/' + urr.getRole());

+							verb = "Extended";

+							participle = "] to User [" ;

+							break;

+						  default:

+							throw new CadiException("Invalid action [" + key + ']');

+						}

+						if (fp.get(AAFcli.timeout())) {

+							pw().print(verb);

+							pw().print(" Role [");

+							pw().print(urr.getRole());

+							pw().print(participle);

+							pw().print(urr.getUser());

+							pw().println(']');

+						} else {

+							switch(fp.code()) {

+							case 202:

+								pw().print("UserRole ");

+								pw().print(option == 0 ? "Creation" : option==1?"Deletion":"Extension");

+								pw().println(" Accepted, but requires Approvals before actualizing");

+								break;

+							case 404:

+								if(option==3) {

+									pw().println("Failed with code 404: UserRole is not found, or you do not have permission to view");

+									break;

+								}

+							default:

+								error(fp);

+							}

+						}

+					}

+				} else {

+					// option 2 is setTo command (an update call)

+					String allRoles = "";

+					if (idx < args.length)

+						allRoles = args[idx++];

+

+					urr.setRole(allRoles);

+					fp = client.update("/authz/userRole/user", getDF(UserRoleRequest.class), urr);

+					if (fp.get(AAFcli.timeout())) {

+						pw().println("Set User's Roles to [" + allRoles + "]");

+					} else {

+						error(fp);

+					}

+				}

+				return fp == null ? 0 : fp.code();

+			}

+		});

+	}

+

+	@Override

+	public void detailedHelp(int indent, StringBuilder sb) {

+		detailLine(sb, indent, "Add OR Delete a User to/from a Role OR");

+		detailLine(sb, indent, "Set a User's Roles to the roles supplied");

+		detailLine(sb, indent + 2, "user    - ID of User");

+		detailLine(sb, indent + 2, "role(s) - Role or Roles to which to add the User");

+		sb.append('\n');

+		detailLine(sb, indent + 2, "Note: this is the same as \"role user add...\" except allows");

+		detailLine(sb, indent + 2, "assignment of user to multiple roles");

+		detailLine(sb, indent + 2, "WARNING: Roles supplied with setTo will be the ONLY roles attached to this user");

+		detailLine(sb, indent + 2, "If no roles are supplied, user's roles are reset.");

+		api(sb, indent, HttpMethods.POST, "authz/userRole", UserRoleRequest.class, true);

+		api(sb, indent, HttpMethods.DELETE, "authz/userRole/<user>/<role>", Void.class, false);

+		api(sb, indent, HttpMethods.PUT, "authz/userRole/<user>", UserRoleRequest.class, false);

+	}

+

+}

diff --git a/authz-cmd/src/main/java/org/onap/aaf/cmd/user/User.java b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/User.java
new file mode 100644
index 0000000..bfc29cf
--- /dev/null
+++ b/authz-cmd/src/main/java/org/onap/aaf/cmd/user/User.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.inno.env.APIException;

+

+public class User extends BaseCmd<User> {

+	public User(AAFcli aafcli) throws APIException {

+		super(aafcli,"user");

+		cmds.add(new Role(this));

+		cmds.add(new Cred(this));

+		cmds.add(new Delg(this));

+		cmds.add(new List(this));

+	}

+}

diff --git a/authz-cmd/src/main/scripts/aaflogin b/authz-cmd/src/main/scripts/aaflogin
new file mode 100644
index 0000000..1c15a43
--- /dev/null
+++ b/authz-cmd/src/main/scripts/aaflogin
@@ -0,0 +1,199 @@
+#!/bin/bash
+JAVA_HOME=_JAVA_HOME_
+JAVA=${JAVA_HOME}/bin/java
+DEFAULT_DOMAIN=XXX_DOMAIN
+###
+# Give some help hints if first run
+#
+if [ "`declare -f aaflogout`" = "" ] || [ "$1" = "-h" ]; then
+  echo
+  echo "  COMMANDS:"
+  echo "    aaflogin -f = Redo Local Login"
+  echo "    aaflogout   = Logout from Environment"
+  echo "    aaflogin -r = Reset Password on AAF Service"
+  echo "    aaflogin -h = Help"
+  echo "    aafcli      = AAF Management Tool"
+  echo
+fi
+
+if [ "$1" != "-h" ]; then
+
+
+###
+# Load User/Password for aafcli, and create in function.
+# 
+# To use, source aaflogin
+#
+#   ex:   . ./aaflogin
+#
+#  -f = force relogin
+#  -r = reset password sequence
+#
+#  see aaflogout to logout
+###
+
+###
+# Gather Classpath - warning, DME2 doesn't work with -Djava.ext.dirs
+###
+AAF_CP=_ROOT_DIR_/etc
+for JAR in `find _ROOT_DIR_/lib -name "*.jar"` ; do
+  AAF_CP="$AAF_CP:$JAR"
+done
+
+###
+# Create Keyfile to use temporarily, if not exists
+###
+if [ ! -e $HOME/.aaf/keyfile ]; then 
+  mkdir -p $HOME/.aaf
+  ${JAVA} -cp $AAF_CP org.onap.aaf.cadi.CmdLine keygen $HOME/.aaf/keyfile
+  chmod 400 $HOME/.aaf/keyfile 
+fi
+  
+###
+# Obtain User ID from AAF_ID, or SUDO_USER or USER, that order
+###
+if [ "$AAF_ID" == "" ] || [ "$1" == "-f" ] ; then
+   if [ "$AAF_ID" == "" ] ; then
+	   if [ "$SUDO_USER" != "" ] ; then 
+	      AAF_ID=$SUDO_USER
+	   else if [ "$USER" != "" ] ; then 
+	      AAF_ID=$USER
+	      fi
+	   fi
+   fi
+
+   echo -n "Enter AAF ID [$AAF_ID]: "
+   read TEMP
+   if [ "$TEMP" != "" ] ; then
+      AAF_ID=$TEMP
+   fi 
+   export AAF_ID
+fi
+
+###
+# Add Function to remove AAF Vars and Functions from the Shell
+#
+function aaflogout {
+	unset AAF_ID
+	unset AAF_PASS
+	unset AAF_CP
+	unset -f aafcli
+	unset -f cmcli
+	unset -f aaflogout
+	rm -f $HOME/.aaf/keyfile
+}
+
+
+###
+# Load the Password
+###
+if [ "$AAF_PASS" == "" ] || [ "$1" == "-f" ] ; then
+   # Ask for User and Password.  Assuming Unix and availability of "stty"
+   if [[ "$AAF_ID" == *"@$DEFAULT_DOMAIN" ]] || [[ "$AAF_ID" != *"@"* ]] ; then
+   	  PASS_PROMPT="AT&T Global Login"
+	  AAF_DEFAULT_DOMAIN="-Daaf_default_domain=$DEFAULT_DOMAIN"
+   else 
+      PASS_PROMPT="AAF"
+      AAF_DEFAULT_DOMAIN=""
+   fi
+  
+   
+   read -ers -p "Enter "$PASS_PROMPT" Password for $AAF_ID: " AAF_PASS
+   echo 
+   AAF_PASS=enc:`$JAVA -cp $AAF_CP $AAF_DEFAULT_DOMAIN org.onap.aaf.cadi.CmdLine digest "$AAF_PASS" $HOME/.aaf/keyfile`
+   export AAF_PASS
+fi
+
+
+
+###
+# load aafcli function in the Shell
+###
+
+function aafcli {
+  # for separating VM_ARGS in aafcli 
+  AAF_SPACE=" "
+  THE_ID=$AAF_ID
+  if [ "${AAF_ID}" = "${AAF_ID/@/%}" ]; then
+	THE_ID+="@$DEFAULT_DOMAIN"
+  fi
+  _JAVA_HOME_/bin/java \
+  -cp $AAF_CP \
+  -Daaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_ \
+  -DAFT_LATITUDE=_AFT_LATITUDE_ \
+  -DAFT_LONGITUDE=_AFT_LONGITUDE_ \
+  -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ \
+  -Daaf_id=$THE_ID \
+  -Daaf_password=$AAF_PASS \
+  -Daaf_dme_timeout=60000 \
+  -Dcadi_keyfile=$HOME/.aaf/keyfile \
+  -Daaf_default_realm=$DEFAULT_DOMAIN \
+  -DDEPLOYED_VERSION=_ARTIFACT_VERSION_ \
+  _DME2_FS_ \
+  com.att.cmd.AAFcli $*  
+  unset THE_ID
+  unset AAF_SPACE
+}
+
+###
+# load cmcli function in the Shell
+###
+
+function cmcli {
+  # for separating VM_ARGS in cmcli 
+  AAF_SPACE=" "
+  THE_ID=$AAF_ID
+  if [ "${AAF_ID}" = "${AAF_ID/@/%}" ]; then
+	THE_ID+="@$DEFAULT_DOMAIN"
+  fi
+  CM_URL=_CM_URL_
+  if [ "${CM_URL}" = "" ]; then
+    CM_URL=https://DME2RESOLVE/service=com.att.authz.Certman/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+  fi
+  
+  _JAVA_HOME_/bin/java \
+  -cp $AAF_CP \
+  -DAFT_LATITUDE=_AFT_LATITUDE_ \
+  -DAFT_LONGITUDE=_AFT_LONGITUDE_ \
+  -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ \
+  -Daaf_dme_timeout=60000 \
+  -Daaf_default_realm=$DEFAULT_DOMAIN \
+  -DDEPLOYED_VERSION=_ARTIFACT_VERSION_ \
+  _DME2_FS_ \
+  org.onap.aaf.cadi.cm.CmAgent cm_url=${CM_URL} aaf_id=$THE_ID aaf_password="$AAF_PASS" \
+    cadi_keyfile=$HOME/.aaf/keyfile $*  
+  unset THE_ID
+  unset AAF_SPACE
+  unset CM_URL
+}
+
+
+###
+# if "-r" the do Remote Password Reset
+###
+if [ "$1" == "-r" ] ; then
+   # Ask for User and Password.  Assuming Unix and availability of "stty"
+   read -ers -p "Enter New AAF Password for $AAF_ID: " AAF_NEWPASS
+   echo 
+   read -ers -p "Reenter New AAF Password for $AAF_ID: " AAF_NEWPASS2
+   echo
+   if [ "$AAF_NEWPASS" == "$AAF_NEWPASS2" ] ; then
+	   RESP=`aafcli user resetCred "$AAF_ID@aaf.att.com" $AAF_NEWPASS`
+	   echo $RESP
+	   if [ "$RESP" == "Reset Credential [$AAF_ID@aaf.att.com]" ] ; then
+	      export AAF_PASS=enc:`$JAVA -cp $AAF_CP org.onap.aaf.cadi.CmdLine digest $AAF_NEWPASS $HOME/.aaf/keyfile`
+	   fi
+   else     
+        echo "Passwords don't match!"
+   fi
+fi
+
+###
+# Export key variables for use in other Scripts
+###
+export AAF_ID 
+export AAF_PASS
+export AAF_CP
+export -f aafcli
+export -f aaflogout
+fi
diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_AAFCli.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_AAFCli.java
new file mode 100644
index 0000000..6a970ce
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_AAFCli.java
@@ -0,0 +1,90 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import static org.junit.Assert.assertTrue;

+import static org.mockito.Mockito.mock;

+

+import java.io.IOException;

+import java.io.OutputStreamWriter;

+import java.net.HttpURLConnection;

+import java.security.GeneralSecurityException;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.cmd.AAFcli;

+

+import org.onap.aaf.cadi.Locator;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.client.PropertyLocator;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.cadi.config.SecurityInfo;

+import org.onap.aaf.cadi.http.HBasicAuthSS;

+import org.onap.aaf.cadi.http.HMangr;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_AAFCli {

+	

+	private static AAFcli cli;

+	private static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF);

+	

+	@BeforeClass

+	public static void setUp() throws Exception, Exception {

+		cli = getAAfCli();

+	}

+	

+	@Test

+	public void eval() throws Exception {

+		assertTrue(cli.eval("#startswith"));

+	}

+	

+	@Test

+	public void eval_empty() throws Exception{

+		assertTrue(cli.eval(""));

+	}

+	

+	@Test

+	public void eval_randomString() throws Exception {

+		assertTrue(cli.eval("Some random string @#&*& to check complete 100 coverage"));

+	}

+	

+	public static AAFcli getAAfCli() throws APIException, LocatorException, GeneralSecurityException, IOException {

+		final AuthzEnv env = new AuthzEnv(System.getProperties());

+		String aafUrl = "https://DME2RESOLVE";

+		SecurityInfo si = new SecurityInfo(env);

+		env.loadToSystemPropsStartsWith("AAF", "DME2");

+		Locator loc;

+		loc = new PropertyLocator(aafUrl);						

+		TIMEOUT = Integer.parseInt(env.getProperty(Config.AAF_CONN_TIMEOUT, Config.AAF_CONN_TIMEOUT_DEF));

+		HMangr hman = new HMangr(env, loc).readTimeout(TIMEOUT).apiVersion("2.0");

+		

+		//TODO: Consider requiring a default in properties

+		env.setProperty(Config.AAF_DEFAULT_REALM, System.getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));

+		HBasicAuthSS ss = mock(HBasicAuthSS.class);

+		return new AAFcli(env, new OutputStreamWriter(System.out), hman, si, ss);

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BaseCmd.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BaseCmd.java
new file mode 100644
index 0000000..a1d19dd
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BaseCmd.java
@@ -0,0 +1,58 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import static org.junit.Assert.assertEquals;

+

+import java.io.IOException;

+import java.security.GeneralSecurityException;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.BaseCmd;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_BaseCmd {

+	

+	private static AAFcli cli;

+	private static BaseCmd bCmd;

+	

+	@BeforeClass

+	public static void setUp() throws APIException, LocatorException, GeneralSecurityException, IOException {

+		cli = JU_AAFCli.getAAfCli();

+		bCmd = new BaseCmd<>(cli, "testString");

+	}

+	

+	@Test

+	public void exec() throws CadiException, APIException, LocatorException {

+		assertEquals(bCmd._exec(0, "add","del","reset","extend"), 0);

+		

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BasicAuth.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BasicAuth.java
new file mode 100644
index 0000000..07f008b
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_BasicAuth.java
@@ -0,0 +1,49 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import static org.junit.Assert.assertEquals;

+

+import java.io.IOException;

+

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.BasicAuth;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_BasicAuth {

+	

+	@Test

+	public void getID () {

+		try {

+			BasicAuth bAuth = new BasicAuth("testUser", "nopass");

+			assertEquals(bAuth.getID(), "testUser");

+			System.out.println(bAuth.getID());

+		} catch (IOException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Help.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Help.java
new file mode 100644
index 0000000..c51246b
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Help.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import static org.junit.Assert.assertEquals;

+

+import java.io.IOException;

+import java.security.GeneralSecurityException;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Cmd;

+import org.onap.aaf.cmd.Help;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Help {

+	

+	private static AAFcli cli;

+	private static Help help;

+	

+	@Mock

+	private static List<Cmd> cmds;

+	

+	@BeforeClass

+	public static void setUp() throws APIException, LocatorException, GeneralSecurityException, IOException {

+		cli = JU_AAFCli.getAAfCli();

+		cmds = new ArrayList<>();

+		help = new Help(cli, cmds);

+	}

+	

+	@Test

+	public void exec_HTTP_200() {

+		try {

+			assertEquals(help._exec(0, "helps"), HttpStatus.OK_200);

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Version.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Version.java
new file mode 100644
index 0000000..3bff61b
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/JU_Version.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd;

+

+import static org.junit.Assert.assertEquals;

+

+import java.io.IOException;

+import java.security.GeneralSecurityException;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.Version;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Version {

+	

+	private static AAFcli cli;

+	private static Version version;

+	

+	@BeforeClass

+	public static void setUp() throws APIException, LocatorException, GeneralSecurityException, IOException {

+		cli = JU_AAFCli.getAAfCli();

+		version = new Version(cli);

+	}

+	

+	@Test

+	public void exec_HTTP_200() throws CadiException, APIException, LocatorException {

+		assertEquals(version._exec(0, "Version"), HttpStatus.OK_200);

+

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Clear.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Clear.java
new file mode 100644
index 0000000..99a2c31
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Clear.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import static org.mockito.Mockito.mock;

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.mgmt.Clear;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Clear {

+	

+	private static Clear clr;

+	

+	@BeforeClass

+	public static void setUp() {

+		clr = mock(Clear.class);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(clr._exec(0, "clear"), 0);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Log.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Log.java
new file mode 100644
index 0000000..04a06f0
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_Log.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import static org.mockito.Mockito.mock;

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.mgmt.Log;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Log {

+	

+	private static Log log;

+	

+	@BeforeClass

+	public static void setUp() {

+		log = mock(Log.class);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(log._exec(0, "session clear"), 0);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_SessClear.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_SessClear.java
new file mode 100644
index 0000000..7cda450
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/mgmt/JU_SessClear.java
@@ -0,0 +1,63 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.mgmt;

+

+import static org.mockito.Mockito.mock;

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.mgmt.SessClear;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_SessClear {

+	

+	private static SessClear sessclr;

+	

+	@BeforeClass

+	public static void setUp() {

+		sessclr = mock(SessClear.class);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(sessclr._exec(0, "session clear"), 0);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Admin.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Admin.java
new file mode 100644
index 0000000..fdecbd1
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Admin.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.Admin;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Admin {

+	

+	private static Admin admin;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		admin = new Admin(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(admin._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Attrib.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Attrib.java
new file mode 100644
index 0000000..ea41bb6
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Attrib.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.Attrib;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Attrib {

+	

+	private static Attrib attrib;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		attrib = new Attrib(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(attrib._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Create.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Create.java
new file mode 100644
index 0000000..af56be5
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Create.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.Create;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Create {

+	

+	private static Create create;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		create = new Create(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(create._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Delete.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Delete.java
new file mode 100644
index 0000000..5d0f7bd
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Delete.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.Delete;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Delete {

+	

+	private static Delete del;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		del = new Delete(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(del._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Describe.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Describe.java
new file mode 100644
index 0000000..1cd7b38
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Describe.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+import static org.mockito.Mockito.CALLS_REAL_METHODS;

+import static org.mockito.Mockito.mock;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.Describe;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Describe {

+	

+	private static Describe desc;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		desc = new Describe(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(desc._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListActivity.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListActivity.java
new file mode 100644
index 0000000..16062b8
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListActivity.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListActivity;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListActivity {

+	

+	private static ListActivity lsActivity;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		lsActivity = new ListActivity(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsActivity._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListAdminResponsible.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListAdminResponsible.java
new file mode 100644
index 0000000..ab28722
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListAdminResponsible.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListAdminResponsible;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListAdminResponsible {

+	

+	private static ListAdminResponsible lsAdminRes;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		lsAdminRes = new ListAdminResponsible(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsAdminRes._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListByName.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListByName.java
new file mode 100644
index 0000000..effa1d4
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListByName.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListByName;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByName {

+	

+	private static ListByName lsByName;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		lsByName = new ListByName(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByName._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListChildren.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListChildren.java
new file mode 100644
index 0000000..f7a850f
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListChildren.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListChildren;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListChildren {

+	

+	private static ListChildren lsChildren;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		lsChildren = new ListChildren(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsChildren._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListNsKeysByAttrib.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListNsKeysByAttrib.java
new file mode 100644
index 0000000..62935a1
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListNsKeysByAttrib.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListNsKeysByAttrib;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListNsKeysByAttrib {

+	

+	private static ListNsKeysByAttrib lsNsKeys;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		lsNsKeys = new ListNsKeysByAttrib(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsNsKeys._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

+

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersInRole.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersInRole.java
new file mode 100644
index 0000000..7fc7af3
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersInRole.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListUsers;

+import org.onap.aaf.cmd.ns.ListUsersInRole;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListUsersInRole {

+	

+	private static ListUsersInRole lsUserinRole;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		ListUsers lsU = new ListUsers(ls);

+		lsUserinRole = new ListUsersInRole(lsU);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsUserinRole._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersWithPerm.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersWithPerm.java
new file mode 100644
index 0000000..fd44a42
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_ListUsersWithPerm.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.List;

+import org.onap.aaf.cmd.ns.ListUsers;

+import org.onap.aaf.cmd.ns.ListUsersWithPerm;

+import org.onap.aaf.cmd.ns.NS;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListUsersWithPerm {

+	

+	private static ListUsersWithPerm lsUserWithPerm;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		List ls = new List(ns);

+		ListUsers lsU = new ListUsers(ls);

+		lsUserWithPerm = new ListUsersWithPerm(lsU);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsUserWithPerm._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Responsible.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Responsible.java
new file mode 100644
index 0000000..77f7a15
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/ns/JU_Responsible.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.ns;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.ns.NS;

+import org.onap.aaf.cmd.ns.Responsible;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Responsible {

+	

+	private static Responsible respsble;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		NS ns = new NS(cli);

+		respsble = new Responsible(ns);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(respsble._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Create.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Create.java
new file mode 100644
index 0000000..82c083b
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Create.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Create;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Create {

+	

+	private static Create create;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		create = new Create(perm);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(create._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Delete.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Delete.java
new file mode 100644
index 0000000..21e7e35
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Delete.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Delete;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Delete {

+	

+	private static Delete del;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		del = new Delete(perm);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(del._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Describe.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Describe.java
new file mode 100644
index 0000000..d05b44e
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Describe.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Describe;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Describe {

+	

+	private static Describe desc;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		desc = new Describe(perm);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(desc._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Grant.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Grant.java
new file mode 100644
index 0000000..a233ca0
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Grant.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Grant;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Grant {

+	

+	private static Grant grant;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		grant = new Grant(perm);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(grant._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListActivity.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListActivity.java
new file mode 100644
index 0000000..c2712be
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListActivity.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.List;

+import org.onap.aaf.cmd.perm.ListActivity;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListActivity {

+	

+	private static ListActivity lsActivity;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		List ls = new List(perm);

+		lsActivity = new ListActivity(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsActivity._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByNS.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByNS.java
new file mode 100644
index 0000000..8935045
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByNS.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.List;

+import org.onap.aaf.cmd.perm.ListByNS;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByNS {

+	

+	private static ListByNS lsByNS;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		List ls = new List(perm);

+		lsByNS = new ListByNS(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByNS._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByName.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByName.java
new file mode 100644
index 0000000..3e59d4e
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByName.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.List;

+import org.onap.aaf.cmd.perm.ListByName;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByName {

+	

+	private static ListByName lsByName;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		List ls = new List(perm);

+		lsByName = new ListByName(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByName._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByRole.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByRole.java
new file mode 100644
index 0000000..d55c0b9
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByRole.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.List;

+import org.onap.aaf.cmd.perm.ListByRole;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByRole {

+	

+	private static ListByRole lsByRole;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		List ls = new List(perm);

+		lsByRole = new ListByRole(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByRole._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByUser.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByUser.java
new file mode 100644
index 0000000..88fef49
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_ListByUser.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.List;

+import org.onap.aaf.cmd.perm.ListByUser;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByUser {

+	

+	private static ListByUser lsByName;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		List ls = new List(perm);

+		lsByName = new ListByUser(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByName._exec(0, "add","del","reset","extend"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Rename.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Rename.java
new file mode 100644
index 0000000..6e53e30
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/perm/JU_Rename.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.perm;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.perm.Rename;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Rename {

+	

+	private static Rename rename;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		Perm perm = new Perm(role);

+		rename = new Rename(perm);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(rename._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_CreateDelete.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_CreateDelete.java
new file mode 100644
index 0000000..9279497
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_CreateDelete.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.CreateDelete;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_CreateDelete {

+	

+	private static CreateDelete createDel;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		createDel = new CreateDelete(role);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(createDel._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_Describe.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_Describe.java
new file mode 100644
index 0000000..388b046
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_Describe.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.Describe;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Describe {

+	

+	private static Describe desc;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		desc = new Describe(role);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(desc._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListActivity.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListActivity.java
new file mode 100644
index 0000000..08dc119
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListActivity.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListActivity;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListActivity {

+	

+	private static ListActivity lsActivity;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsActivity = new ListActivity(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsActivity._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNS.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNS.java
new file mode 100644
index 0000000..82133fa
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNS.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListByNS;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByNS {

+	

+	private static ListByNS lsByNS;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsByNS = new ListByNS(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByNS._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNameOnly.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNameOnly.java
new file mode 100644
index 0000000..266039a
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByNameOnly.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListByNameOnly;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByNameOnly {

+	

+	private static ListByNameOnly lsByName;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsByName = new ListByNameOnly(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByName._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByPerm.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByPerm.java
new file mode 100644
index 0000000..f97a684
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByPerm.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListByPerm;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByPerm {

+	

+	private static ListByPerm lsByPerm;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsByPerm = new ListByPerm(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByPerm._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByRole.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByRole.java
new file mode 100644
index 0000000..0848eb1
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByRole.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListByRole;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByRole {

+	

+	private static ListByRole lsByRole;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsByRole = new ListByRole(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByRole._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByUser.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByUser.java
new file mode 100644
index 0000000..17f9981
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_ListByUser.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.role.List;

+import org.onap.aaf.cmd.role.ListByUser;

+import org.onap.aaf.cmd.role.Role;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListByUser {

+	

+	private static ListByUser lsByUser;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		List ls = new List(role);

+		lsByUser = new ListByUser(ls);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsByUser._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_User.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_User.java
new file mode 100644
index 0000000..cadfd94
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/role/JU_User.java
@@ -0,0 +1,68 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.role;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.perm.Perm;

+import org.onap.aaf.cmd.role.Role;

+import org.onap.aaf.cmd.role.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_User {

+	

+	private static User user;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		Role role = new Role(cli);

+		user = new User(role);

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(user._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Cred.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Cred.java
new file mode 100644
index 0000000..77c05a9
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Cred.java
@@ -0,0 +1,116 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotNull;

+import static org.mockito.Mockito.mock;

+import static org.mockito.Mockito.when;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.user.Cred;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Cred {

+

+	private static Cred testCred;

+	private static User testUser;

+

+

+	@BeforeClass

+	public static void setUp() {

+		testCred = mock(Cred.class);

+		testUser = mock(User.class);

+		try {

+			when(testCred._exec(4, "String1","String2","String3","String4")).thenReturn(10);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (APIException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+	@Test

+	public void exec() throws CadiException, APIException, LocatorException {

+		assertEquals(testCred._exec(4, "String1","String2","String3","String4"), 10);

+	}

+

+

+	@Test

+	public void exec_add() {		

+		try {

+			assertNotNull(testCred._exec(0, "zeroed","add","del","reset","extend"));

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+

+	}

+

+	@Test

+	public void exec_del() {		

+		try {

+			assertNotNull(testCred._exec(1, "zeroed","add","del","reset","extend"));

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+

+	}

+

+	@Test

+	public void exec_reset() {		

+		try {

+			assertNotNull(testCred._exec(2, "zeroed","add","del","reset","extend"));

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+

+	}

+

+	@Test

+	public void exec_extend() {		

+		try {

+			assertNotNull(testCred._exec(3, "zeroed","add","del","reset","extend"));

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+

+	}

+

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Delg.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Delg.java
new file mode 100644
index 0000000..4170846
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Delg.java
@@ -0,0 +1,81 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.mockito.Mockito.mock;

+import static org.junit.Assert.*;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.user.Delg;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Delg {

+	

+	private static User testUser;

+	private static Delg delg;

+	

+	@BeforeClass

+	public static void setUp() throws APIException {

+		testUser = mock(User.class);

+		delg = mock(Delg.class);

+	}

+	

+	@Test

+	public void exec_add() {

+		try {

+			assertEquals(delg._exec(0, "zero","add","upd","del"), 0);

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void exec_upd() {

+		try {

+			assertEquals(delg._exec(1, "zero","add","upd","del"), 0);

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void exec_del() {

+		try {

+			assertEquals(delg._exec(2, "zero","add","upd","del"), 0);

+		} catch (CadiException | APIException | LocatorException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListActivity.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListActivity.java
new file mode 100644
index 0000000..8edc633
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListActivity.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListActivity;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListActivity {

+	

+	private static ListActivity lsActivity;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsActivity = new ListActivity(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsActivity._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListApprovals.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListApprovals.java
new file mode 100644
index 0000000..fe3b91c
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListApprovals.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListApprovals;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListApprovals {

+	

+	private static ListApprovals lsApprovals;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsApprovals = new ListApprovals(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsApprovals._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListDelegates.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListDelegates.java
new file mode 100644
index 0000000..e25cedf
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListDelegates.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListDelegates;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListDelegates {

+	

+	private static ListDelegates lsDelegates;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsDelegates = new ListDelegates(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsDelegates._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForCreds.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForCreds.java
new file mode 100644
index 0000000..95012bd
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForCreds.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListForCreds;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListForCreds {

+	

+	private static ListForCreds lsForCreds;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsForCreds = new ListForCreds(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsForCreds._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForPermission.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForPermission.java
new file mode 100644
index 0000000..bb1e3db
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForPermission.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListForPermission;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListForPermission {

+	

+	private static ListForPermission lsForPermission;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsForPermission = new ListForPermission(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsForPermission._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForRoles.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForRoles.java
new file mode 100644
index 0000000..e2b5cfe
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_ListForRoles.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.List;

+import org.onap.aaf.cmd.user.ListForRoles;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_ListForRoles {

+	

+	private static ListForRoles lsForRoles;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		List parent = new List(usr);

+		lsForRoles = new ListForRoles(parent);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(lsForRoles._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Role.java b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Role.java
new file mode 100644
index 0000000..133adf7
--- /dev/null
+++ b/authz-cmd/src/test/java/org/onap/aaf/cmd/user/JU_Role.java
@@ -0,0 +1,68 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cmd.user;

+

+import static org.junit.Assert.assertEquals;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.cmd.AAFcli;

+import org.onap.aaf.cmd.JU_AAFCli;

+import org.onap.aaf.cmd.user.Role;

+import org.onap.aaf.cmd.user.User;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_Role {

+	

+	private static Role role;

+	

+	@BeforeClass

+	public static void setUp () throws NoSuchFieldException, SecurityException, Exception, IllegalAccessException {

+		AAFcli cli = JU_AAFCli.getAAfCli();

+		User usr = new User(cli);

+		role = new Role(usr);

+		

+	}

+	

+	@Test

+	public void exec() {

+		try {

+			assertEquals(role._exec(0, "add","del","reset","extend","clear", "rename", "create"),500);

+		} catch (CadiException e) {

+			

+			e.printStackTrace();

+		} catch (APIException e) {

+			

+			e.printStackTrace();

+		} catch (LocatorException e) {

+			

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-core/pom.xml b/authz-core/pom.xml
new file mode 100644
index 0000000..085110d
--- /dev/null
+++ b/authz-core/pom.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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/xsd/maven-4.0.0.xsd">

+	<modelVersion>4.0.0</modelVersion>

+	<parent>

+		<groupId>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-core</artifactId>

+	<name>Authz Core</name>

+	<description>Core Libraries 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>

+	<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+</properties>

+	<dependencies>

+		<dependency>

+			<groupId>org.onap.aaf.inno</groupId>

+			<artifactId>env</artifactId>

+		</dependency>

+		<dependency>

+			<groupId>org.onap.aaf.inno</groupId>

+			<artifactId>log4j</artifactId>

+		</dependency>

+		<dependency>

+			<groupId>org.onap.aaf.inno</groupId>

+			<artifactId>rosetta</artifactId>

+		</dependency>

+		<dependency>

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+				<exclusions>

+				  <exclusion> 

+ 					<groupId>javax.servlet</groupId>

+        			<artifactId>servlet-api</artifactId>

+        		   </exclusion>

+			    </exclusions> 

+			

+		</dependency>

+		<dependency>

+		  <groupId>javax.servlet</groupId>

+		  <artifactId>servlet-api</artifactId>

+  		</dependency>

+

+	</dependencies>

+

+	<build>

+		<plugins>

+		</plugins>

+		<pluginManagement>

+			<plugins>

+			 

+				<plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<version>2.6</version>

+					<configuration>

+						<skip>false</skip>

+					</configuration>

+			    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin>

+		

+			</plugins>

+		</pluginManagement>

+	</build>

+	<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+	

+</project>

+

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/common/Define.java b/authz-core/src/main/java/org/onap/aaf/authz/common/Define.java
new file mode 100644
index 0000000..58a8674
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/common/Define.java
@@ -0,0 +1,50 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.common;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.Env;

+

+public class Define {

+	public static String ROOT_NS="NS.Not.Set";

+	public static String ROOT_COMPANY=ROOT_NS;

+

+	public static void set(Env env) throws CadiException {

+		ROOT_NS = env.getProperty(Config.AAF_ROOT_NS);

+		if(ROOT_NS==null) {

+			throw new CadiException(Config.AAF_ROOT_NS + " property is required.");

+		}

+		ROOT_COMPANY = env.getProperty(Config.AAF_ROOT_COMPANY);

+		if(ROOT_COMPANY==null) {

+			int last = ROOT_NS.lastIndexOf('.');

+			if(last>=0) {

+				ROOT_COMPANY = ROOT_NS.substring(0, last);

+			} else {

+				throw new CadiException(Config.AAF_ROOT_COMPANY + " or " + Config.AAF_ROOT_NS + " property with 3 positions is required.");

+			}

+		}

+		env.init().log("AAF Root NS is " + ROOT_NS + ", and AAF Root Company is " +ROOT_COMPANY);

+	}

+	

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzEnv.java b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzEnv.java
new file mode 100644
index 0000000..3025e5c
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzEnv.java
@@ -0,0 +1,264 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.io.ByteArrayOutputStream;

+import java.io.IOException;

+import java.io.InputStream;

+import java.util.Map.Entry;

+import java.util.Properties;

+

+import org.onap.aaf.cadi.Access;

+import org.onap.aaf.cadi.Symm;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Decryptor;

+import org.onap.aaf.inno.env.Encryptor;

+import org.onap.aaf.inno.env.impl.Log4JLogTarget;

+import org.onap.aaf.inno.env.log4j.LogFileNamer;

+import org.onap.aaf.rosetta.env.RosettaEnv;

+

+

+/**

+ * AuthzEnv is the Env tailored to Authz Service

+ * 

+ * Most of it is derived from RosettaEnv, but it also implements Access, which

+ * is an Interface that Allows CADI to interact with Container Logging

+ * 

+ *

+ */

+public class AuthzEnv extends RosettaEnv implements Access {

+	private long[] times = new long[20];

+	private int idx = 0;

+	//private int mask = Level.AUDIT.maskOf();

+

+	public AuthzEnv() {

+		super();

+	}

+

+	public AuthzEnv(String ... args) {

+		super(args);

+	}

+

+	public AuthzEnv(Properties props) {

+		super(Config.CADI_PROP_FILES,props);

+	}

+	

+

+	@Override

+	public AuthzTransImpl newTrans() {

+		synchronized(this) {

+			times[idx]=System.currentTimeMillis();

+			if(++idx>=times.length)idx=0;

+		}

+		return new AuthzTransImpl(this);

+	}

+

+	/**

+	 *  Create a Trans, but do not include in Weighted Average

+	 * @return

+	 */

+	public AuthzTrans newTransNoAvg() {

+		return new AuthzTransImpl(this);

+	}

+

+	public long transRate() {

+		int count = 0;

+		long pot = 0;

+		long prev = 0;

+		for(int i=idx;i<times.length;++i) {

+			if(times[i]>0) {

+				if(prev>0) {

+					++count;

+		pot += times[i]-prev;

+				}

+				prev = times[i]; 

+			}

+		}

+		for(int i=0;i<idx;++i) {

+			if(times[i]>0) {

+				if(prev>0) {

+					++count;

+					pot += times[i]-prev;

+				}

+				prev = times[i]; 

+			}

+		}

+

+		return count==0?300000L:pot/count; // Return Weighted Avg, or 5 mins, if none avail.

+	}

+	

+	@Override

+	public ClassLoader classLoader() {

+		return getClass().getClassLoader();

+	}

+

+	@Override

+	public void load(InputStream is) throws IOException {

+		Properties props = new Properties();

+		props.load(is);

+		for(Entry<Object, Object> es : props.entrySet()) {

+			String key = es.getKey().toString();

+			String value =es.getValue().toString();

+			put(staticSlot(key==null?null:key.trim()),value==null?null:value.trim());

+		}

+	}

+

+	@Override

+	public void log(Level lvl, Object... msgs) {

+//		if(lvl.inMask(mask)) {

+//			switch(lvl) {

+//				case INIT:

+//					init().log(msgs);

+//					break;

+//				case AUDIT:

+//					audit().log(msgs);

+//					break;

+//				case DEBUG:

+//					debug().log(msgs);

+//					break;

+//				case ERROR:

+//					error().log(msgs);

+//					break;

+//				case INFO:

+//					info().log(msgs);

+//					break;

+//				case WARN:

+//					warn().log(msgs);

+//					break;

+//				case NONE:

+//					break;

+//			}

+//		}

+	}

+

+	@Override

+	public void log(Exception e, Object... msgs) {

+		error().log(e,msgs);

+	}

+

+	//@Override

+	public void printf(Level level, String fmt, Object... elements) {

+		if(willLog(level)) {

+			log(level,String.format(fmt, elements));

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.cadi.Access#willLog(org.onap.aaf.cadi.Access.Level)

+	 */

+	@Override

+	public boolean willLog(Level level) {

+		

+//		if(level.inMask(mask)) {

+//			switch(level) {

+//				case INIT:

+//					return init().isLoggable();

+//				case AUDIT:

+//					return audit().isLoggable();

+//				case DEBUG:

+//					return debug().isLoggable();

+//				case ERROR:

+//					return error().isLoggable();

+//				case INFO:

+//					return info().isLoggable();

+//				case WARN:

+//					return warn().isLoggable();

+//				case NONE:

+//					return false;

+//			}

+//		}

+		return false;

+	}

+

+	@Override

+	public void setLogLevel(Level level) {

+		super.debug().isLoggable();

+		//level.toggle(mask);

+	}

+

+	public void setLog4JNames(String path, String root, String _service, String _audit, String _init, String _trace) throws APIException {

+		LogFileNamer lfn = new LogFileNamer(root);

+		if(_service==null) {

+			throw new APIException("AuthzEnv.setLog4JNames \"_service\" required (as default).  Others can be null");

+		}

+		String service=_service=lfn.setAppender(_service); // when name is split, i.e. authz|service, the Appender is "authz", and "service"

+		String audit=_audit==null?service:lfn.setAppender(_audit);     // is part of the log-file name

+		String init=_init==null?service:lfn.setAppender(_init);

+		String trace=_trace==null?service:lfn.setAppender(_trace);

+		//TODO Validate path on Classpath

+		lfn.configure(path);

+		super.fatal = new Log4JLogTarget(service,org.apache.log4j.Level.FATAL);

+		super.error = new Log4JLogTarget(service,org.apache.log4j.Level.ERROR);

+		super.warn = new Log4JLogTarget(service,org.apache.log4j.Level.WARN);

+		super.audit = new Log4JLogTarget(audit,org.apache.log4j.Level.WARN);

+		super.init = new Log4JLogTarget(init,org.apache.log4j.Level.WARN);

+		super.info = new Log4JLogTarget(service,org.apache.log4j.Level.INFO);

+		super.debug = new Log4JLogTarget(service,org.apache.log4j.Level.DEBUG);

+		super.trace = new Log4JLogTarget(trace,org.apache.log4j.Level.TRACE);

+	}

+	

+	private static final byte[] ENC="enc:???".getBytes();

+	public String decrypt(String encrypted, final boolean anytext) throws IOException {

+		if(encrypted==null) {

+			throw new IOException("Password to be decrypted is null");

+		}

+		if(anytext || encrypted.startsWith("enc:")) {

+			if(decryptor.equals(Decryptor.NULL) && getProperty(Config.CADI_KEYFILE)!=null) {

+				final Symm s = Symm.obtain(this);

+				decryptor = new Decryptor() {

+					private Symm symm = s;

+					@Override

+					public String decrypt(String encrypted) {

+						try {

+							return (encrypted!=null && (anytext || encrypted.startsWith(Symm.ENC)))

+									? symm.depass(encrypted)

+									: encrypted;

+						} catch (IOException e) {

+							return "";

+						}

+					}

+				};

+				encryptor = new Encryptor() {

+					@Override

+					public String encrypt(String data) {

+						ByteArrayOutputStream baos = new ByteArrayOutputStream();

+						try {

+							baos.write(ENC);

+							return "enc:???"+s.enpass(data);

+						} catch (IOException e) {

+							return "";

+						}

+					}

+	

+				};

+			}

+			return decryptor.decrypt(encrypted);

+		} else {

+			return encrypted;

+		}

+	}

+	

+	

+	

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTrans.java b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTrans.java
new file mode 100644
index 0000000..cd4da45
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTrans.java
@@ -0,0 +1,71 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.security.Principal;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.org.Organization;

+

+import org.onap.aaf.cadi.Lur;

+import org.onap.aaf.cadi.Permission;

+import org.onap.aaf.inno.env.LogTarget;

+import org.onap.aaf.inno.env.TransStore;

+

+public interface AuthzTrans extends TransStore {

+	public abstract AuthzTrans set(HttpServletRequest req);

+

+	public abstract void setUser(Principal p);

+	

+	public abstract String user();

+

+	public abstract Principal getUserPrincipal();

+

+	public abstract String ip();

+

+	public abstract int port();

+

+	public abstract String meth();

+

+	public abstract String path();

+

+	public abstract String agent();

+	

+	public abstract AuthzEnv env();

+

+	public abstract void setLur(Lur lur);

+

+	public abstract boolean fish(Permission p);

+	

+	public abstract boolean forceRequested();

+	

+	public abstract Organization org();

+

+	public abstract boolean moveRequested();

+

+	public abstract boolean futureRequested();

+	

+	public abstract void logAuditTrail(LogTarget lt);

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransFilter.java b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransFilter.java
new file mode 100644
index 0000000..31c13e6
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransFilter.java
@@ -0,0 +1,165 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.security.Principal;

+

+import javax.servlet.ServletRequest;

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.cssa.rserv.TransFilter;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.Connector;

+import org.onap.aaf.cadi.TrustChecker;

+import org.onap.aaf.cadi.principal.BasicPrincipal;

+import org.onap.aaf.cadi.principal.TrustPrincipal;

+import org.onap.aaf.cadi.principal.X509Principal;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans.Metric;

+

+public class AuthzTransFilter extends TransFilter<AuthzTrans> {

+	private AuthzEnv env;

+	public Metric serviceMetric;

+	public static Slot transIDslot;

+

+	public static final String TRANS_ID_SLOT = "TRANS_ID_SLOT";

+	public static final int BUCKETSIZE = 2;

+

+	public AuthzTransFilter(AuthzEnv env, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException {

+		super(env,con, tc, additionalTafLurs);

+		this.env = env;

+		serviceMetric = new Metric();

+		serviceMetric.buckets = new float[BUCKETSIZE];

+		if(transIDslot==null) {

+			transIDslot = env.slot(TRANS_ID_SLOT);

+		}

+	}

+	

+	@Override

+	protected AuthzTrans newTrans() {

+		AuthzTrans at = env.newTrans();

+		at.setLur(getLur());

+		return at;

+	}

+

+	@Override

+	protected TimeTaken start(AuthzTrans trans, ServletRequest request) {

+		trans.set((HttpServletRequest)request);

+		return trans.start("Trans " + //(context==null?"n/a":context.toString()) +

+		" IP: " + trans.ip() +

+		" Port: " + trans.port()

+		, Env.SUB);

+	}

+

+	@Override

+	protected void authenticated(AuthzTrans trans, Principal p) {

+		trans.setUser(p);

+	}

+

+	@Override

+	protected void tallyHo(AuthzTrans trans) {

+		if(trans.info().isLoggable()) {

+			// Transaction is done, now post

+			StringBuilder sb = new StringBuilder("AuditTrail\n");

+			// We'll grabAct sub-metrics for Remote Calls and JSON

+			// IMPORTANT!!! if you add more entries here, change "BUCKETSIZE"!!!

+			Metric m = trans.auditTrail(1, sb, Env.REMOTE,Env.JSON);

+

+			// Add current Metrics to total metrics

+			serviceMetric.total+= m.total;

+			for(int i=0;i<serviceMetric.buckets.length;++i) {

+				serviceMetric.buckets[i]+=m.buckets[i];

+			}

+			

+			// Log current info

+			sb.append("  Total: ");

+			sb.append(m.total);

+			sb.append(" Remote: ");

+			sb.append(m.buckets[0]);

+			sb.append(" JSON: ");

+			sb.append(m.buckets[1]);

+			trans.info().log(sb);

+		} else {

+			// IMPORTANT!!! if you add more entries here, change "BUCKETSIZE"!!!

+			StringBuilder content = new StringBuilder(); 

+			Metric m = trans.auditTrail(1, content, Env.REMOTE,Env.JSON);

+			// Add current Metrics to total metrics

+			serviceMetric.total+= m.total;

+			for(int i=0;i<serviceMetric.buckets.length;++i) {

+				serviceMetric.buckets[i]+=m.buckets[i];

+			}

+			

+			StringBuilder sb = new StringBuilder();

+			sb.append("user=");

+			Principal p = trans.getUserPrincipal();

+			if(p==null) {

+				sb.append("n/a");

+			} else {

+				sb.append(p.getName());

+				if(p instanceof TrustPrincipal) {

+					sb.append('(');

+					sb.append(((TrustPrincipal)p).getOrigName());

+					sb.append(')');

+				} else {

+					sb.append('[');

+					if(p instanceof X509Principal) {

+						sb.append("x509");

+					} else if(p instanceof BasicPrincipal) {

+						sb.append("BAth");

+					} else {

+						sb.append(p.getClass().getSimpleName());

+					}

+					sb.append(']');

+				}

+			}

+			sb.append(",ip=");

+			sb.append(trans.ip());

+			sb.append(",port=");

+			sb.append(trans.port());

+			sb.append(",ms=");

+			sb.append(m.total);

+			sb.append(",meth=");

+			sb.append(trans.meth());

+			sb.append(",path=");

+			sb.append(trans.path());

+

+			Long tsi;

+			if((tsi=trans.get(transIDslot, null))!=null) {

+				sb.append(",traceID=");

+				sb.append(Long.toHexString(tsi));

+			}

+				

+			if(content.length()>0) {

+				sb.append(",msg=\"");

+				sb.append(content);

+				sb.append('"');

+			}

+			

+			trans.warn().log(sb);

+		}

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransImpl.java b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransImpl.java
new file mode 100644
index 0000000..40cdb7f
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransImpl.java
@@ -0,0 +1,198 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.security.Principal;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.OrganizationFactory;

+

+import org.onap.aaf.cadi.Lur;

+import org.onap.aaf.cadi.Permission;

+import org.onap.aaf.inno.env.LogTarget;

+import org.onap.aaf.inno.env.impl.BasicTrans;

+

+public class AuthzTransImpl extends BasicTrans implements AuthzTrans {

+	private static final String TRUE = "true";

+	private Principal user;

+	private String ip,agent,meth,path;

+	private int port;

+	private Lur lur;

+	private Organization org;

+	private String force;

+	private boolean futureRequested;

+

+	public AuthzTransImpl(AuthzEnv env) {

+		super(env);

+		ip="n/a";

+		org=null;

+	}

+

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#set(javax.servlet.http.HttpServletRequest)

+	 */

+	@Override

+	public AuthzTrans set(HttpServletRequest req) {

+		user = req.getUserPrincipal();

+		ip = req.getRemoteAddr();

+		port = req.getRemotePort();

+		agent = req.getHeader("User-Agent");

+		meth = req.getMethod();

+		path = req.getPathInfo();

+		force = req.getParameter("force");

+		futureRequested = TRUE.equalsIgnoreCase(req.getParameter("request"));

+		org=null;

+		return this;

+	}

+	

+	@Override

+	public void setUser(Principal p) {

+		user = p;

+	}

+

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#user()

+	 */

+	@Override

+	public String user() {

+		return user==null?"n/a":user.getName();

+	}

+	

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#getUserPrincipal()

+	 */

+	@Override

+	public Principal getUserPrincipal() {

+		return user;

+	}

+

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#ip()

+	 */

+	@Override

+	public String ip() {

+		return ip;

+	}

+

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#port()

+	 */

+	@Override

+	public int port() {

+		return port;

+	}

+

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.env.AuthzTrans#meth()

+	 */

+	@Override

+	public String meth() {

+		return meth;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.env.AuthzTrans#path()

+	 */

+	@Override

+	public String path() {

+		return path;

+	}

+

+	/**

+	 * @see org.onap.aaf.authz.env.AuthTrans#agent()

+	 */

+	@Override

+	public String agent() {

+		return agent;

+	}

+

+	@Override

+	public AuthzEnv env() {

+		return (AuthzEnv)delegate;

+	}

+	

+	@Override

+	public boolean forceRequested() {

+		return TRUE.equalsIgnoreCase(force);

+	}

+	

+	public void forceRequested(boolean force) {

+		this.force = force?TRUE:"false";

+	}

+	

+	@Override

+	public boolean moveRequested() {

+		return "move".equalsIgnoreCase(force);

+	}

+

+	@Override

+	public boolean futureRequested() {

+		return futureRequested;

+	}

+	

+

+	@Override

+	public void setLur(Lur lur) {

+		this.lur = lur;

+	}

+	

+	@Override

+	public boolean fish(Permission p) {

+		if(lur!=null) {

+			return lur.fish(user, p);

+		}

+		return false;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.env.AuthzTrans#org()

+	 */

+	@Override

+	public Organization org() {

+		if(org==null) {

+			try {

+				if((org = OrganizationFactory.obtain(env(), user()))==null) {

+					org = Organization.NULL;

+				}

+			} catch (Exception e) {

+				org = Organization.NULL;

+			}

+		} 

+		return org;

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.env.AuthzTrans#logAuditTrailOnly(org.onap.aaf.inno.env.LogTarget)

+	 */

+	@Override

+	public void logAuditTrail(LogTarget lt) {

+		if(lt.isLoggable()) {

+			StringBuilder sb = new StringBuilder();

+			auditTrail(1, sb);

+			lt.log(sb);

+		}

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransOnlyFilter.java b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransOnlyFilter.java
new file mode 100644
index 0000000..d1be857
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/AuthzTransOnlyFilter.java
@@ -0,0 +1,89 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.security.Principal;

+

+import javax.servlet.ServletRequest;

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.cssa.rserv.TransOnlyFilter;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans.Metric;

+

+public class AuthzTransOnlyFilter extends TransOnlyFilter<AuthzTrans> {

+	private AuthzEnv env;

+	public Metric serviceMetric;

+

+	public static final int BUCKETSIZE = 2;

+

+	public AuthzTransOnlyFilter(AuthzEnv env) {

+		this.env = env;

+		serviceMetric = new Metric();

+		serviceMetric.buckets = new float[BUCKETSIZE]; 

+	}

+	

+	@Override

+	protected AuthzTrans newTrans() {

+		return env.newTrans();

+	}

+

+	@Override

+	protected TimeTaken start(AuthzTrans trans, ServletRequest request) {

+		trans.set((HttpServletRequest)request);

+		return trans.start("Trans " + //(context==null?"n/a":context.toString()) +

+		" IP: " + trans.ip() +

+		" Port: " + trans.port()

+		, Env.SUB);

+	}

+

+	@Override

+	protected void authenticated(AuthzTrans trans, Principal p) {

+		trans.setUser(p);

+	}

+

+	@Override

+	protected void tallyHo(AuthzTrans trans) {

+		// Transaction is done, now post

+		StringBuilder sb = new StringBuilder("AuditTrail\n");

+		// We'll grab sub-metrics for Remote Calls and JSON

+		// IMPORTANT!!! if you add more entries here, change "BUCKETSIZE"!!!

+		Metric m = trans.auditTrail(1, sb, Env.REMOTE,Env.JSON);

+		// Add current Metrics to total metrics

+		serviceMetric.total+= m.total;

+		for(int i=0;i<serviceMetric.buckets.length;++i) {

+			serviceMetric.buckets[i]+=m.buckets[i];

+		}

+		// Log current info

+		sb.append("  Total: ");

+		sb.append(m.total);

+		sb.append(" Remote: ");

+		sb.append(m.buckets[0]);

+		sb.append(" JSON: ");

+		sb.append(m.buckets[1]);

+		trans.info().log(sb);

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/env/NullTrans.java b/authz-core/src/main/java/org/onap/aaf/authz/env/NullTrans.java
new file mode 100644
index 0000000..62ebe52
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/env/NullTrans.java
@@ -0,0 +1,225 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import java.security.Principal;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.org.Organization;

+

+import org.onap.aaf.cadi.Lur;

+import org.onap.aaf.cadi.Permission;

+import org.onap.aaf.inno.env.Decryptor;

+import org.onap.aaf.inno.env.Encryptor;

+import org.onap.aaf.inno.env.LogTarget;

+import org.onap.aaf.inno.env.Slot;

+import org.onap.aaf.inno.env.StaticSlot;

+import org.onap.aaf.inno.env.TimeTaken;

+

+/**

+ * A NULL implementation of AuthzTrans, for use in DirectAAF Taf/Lurs

+ */

+public class NullTrans implements AuthzTrans {

+	private static final AuthzTrans singleton = new NullTrans();

+	

+	public static final AuthzTrans singleton() {

+		return singleton;

+	}

+	

+	public void checkpoint(String text) {}

+	public void checkpoint(String text, int additionalFlag) {}

+	public Metric auditTrail(int indent, StringBuilder sb, int... flag) {return null;}

+	public LogTarget fatal() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget error() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget audit() {

+		return LogTarget.NULL;

+	}

+

+	/* (non-Javadoc)

+	 * @see com.att.env.Env#init()

+	 */

+	@Override

+	public LogTarget init() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget warn() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget info() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget debug() {

+		return LogTarget.NULL;

+	}

+

+	public LogTarget trace() {

+		return LogTarget.NULL;

+	}

+

+	public TimeTaken start(String name, int flag) {

+		return new TimeTaken(name,flag) {

+			public void output(StringBuilder sb) {

+				sb.append(name);

+				sb.append(' ');

+				sb.append(millis());

+				sb.append("ms");

+			}

+		};

+	}

+

+	@Override

+	public String setProperty(String tag, String value) {

+		return value;

+	}

+

+	@Override

+	public String getProperty(String tag) {

+		return tag;

+	}

+

+	@Override

+	public String getProperty(String tag, String deflt) {

+		return deflt;

+	}

+

+	@Override

+	public Decryptor decryptor() {

+		return null;

+	}

+

+	@Override

+	public Encryptor encryptor() {

+		return null;

+	}

+	@Override

+	public AuthzTrans set(HttpServletRequest req) {

+		return null;

+	}

+

+	@Override

+	public String user() {

+		return null;

+	}

+

+	@Override

+	public Principal getUserPrincipal() {

+		return null;

+	}

+

+	@Override

+	public String ip() {

+		return null;

+	}

+

+	@Override

+	public int port() {

+		return 0;

+	}

+	@Override

+	public String meth() {

+		return null;

+	}

+

+	@Override

+	public String path() {

+		return null;

+	}

+

+	@Override

+	public void put(Slot slot, Object value) {

+	}

+	@Override

+	public <T> T get(Slot slot, T deflt) {

+		return null;

+	}

+	@Override

+	public <T> T get(StaticSlot slot, T dflt) {

+		return null;

+	}

+	@Override

+	public void setUser(Principal p) {

+	}

+	@Override

+	public Slot slot(String name) {

+		return null;

+	}

+	@Override

+	public AuthzEnv env() {

+		return null;

+	}

+	@Override

+	public String agent() {

+		return null;

+	}

+

+	@Override

+	public void setLur(Lur lur) {

+	}

+

+	@Override

+	public boolean fish(Permission p) {

+		return false;

+	}

+

+	@Override

+	public boolean forceRequested() {

+		return false;

+	}

+

+	@Override

+	public boolean futureRequested() {

+		return false;

+	}

+

+	@Override

+	public boolean moveRequested() {

+		return false;

+	}

+

+	@Override

+	public Organization org() {

+		return Organization.NULL;

+	}

+

+	@Override

+	public void logAuditTrail(LogTarget lt) {

+	}

+

+	@Override

+	public Metric auditTrail(LogTarget lt, int indent, StringBuilder sb, int... flag) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+

+}

+

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/layer/FacadeImpl.java b/authz-core/src/main/java/org/onap/aaf/authz/layer/FacadeImpl.java
new file mode 100644
index 0000000..7f1fef8
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/layer/FacadeImpl.java
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.layer;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Data.TYPE;

+

+

+

+public abstract class FacadeImpl {

+	protected static final String IN = "in";

+

+	protected void setContentType(HttpServletResponse response, TYPE type) {

+		response.setContentType(type==Data.TYPE.JSON?"application/json":"text.xml");

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/layer/Result.java b/authz-core/src/main/java/org/onap/aaf/authz/layer/Result.java
new file mode 100644
index 0000000..7b7bcd0
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/layer/Result.java
@@ -0,0 +1,325 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.layer;

+

+import java.util.Collection;

+import java.util.List;

+import java.util.Set;

+

+

+/**

+ * It would be nice if Java Enums were extensible, but they're not.

+ * 

+ *

+ */

+public class Result<RV> {

+    private static final String SUCCESS = "Success";

+    public static final String[] EMPTY_VARS = new String[0];

+

+	public final static int OK=0,

+							ERR_Security 				= 1,

+							ERR_Denied 					= 2,

+							ERR_Policy 					= 3,

+							ERR_BadData 				= 4,

+							ERR_NotImplemented 			= 5,

+    	    				ERR_NotFound 				= 6,

+    						ERR_ConflictAlreadyExists 	= 7,

+    						ERR_ActionNotCompleted 		= 8,

+							ERR_Backend					= 9,

+							ERR_General					= 20;

+							

+	public final RV value;

+	public final int status;

+	public final String details;

+	public final String[] variables;

+	

+	protected Result(RV value, int status, String details, String[] variables) {

+		this.value = value;

+	    if(value==null) {

+		specialCondition|=EMPTY_LIST;

+	    }

+	    this.status = status;

+	    this.details = details;

+	    if(variables==null) {

+		    this.variables = EMPTY_VARS;

+	    } else {

+	    	this.variables=variables;

+	    }

+	}

+	

+    /**

+     * Create a Result class with "OK" status and "Success" for details

+     * 

+     * This is the easiest to use

+     * 

+     * @param value

+     * @param status

+     * @return

+     */

+    public static<R> Result<R> ok(R value) {

+    	return new Result<R>(value,OK,SUCCESS,null);

+    }

+

+    /**

+     * Accept Arrays and mark as empty or not

+     * @param value

+     * @return

+     */

+    public static<R> Result<R[]> ok(R value[]) {

+    	return new Result<R[]>(value,OK,SUCCESS,null).emptyList(value.length==0);

+    }

+

+    /**

+     * Accept Sets and mark as empty or not

+     * @param value

+     * @return

+     */

+    public static<R> Result<Set<R>> ok(Set<R> value) {

+    	return new Result<Set<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);

+    }

+

+    /**

+     * Accept Lists and mark as empty or not

+     * @param value

+     * @return

+     */

+    public static<R> Result<List<R>> ok(List<R> value) {

+    	return new Result<List<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);

+    }

+

+    /**

+     * Accept Collections and mark as empty or not

+     * @param value

+     * @return

+     */

+    public static<R> Result<Collection<R>> ok(Collection<R> value) {

+    	return new Result<Collection<R>>(value,OK,SUCCESS,null).emptyList(value.size()==0);

+    }

+

+

+    /**

+     * Special Case for Void Type

+     * @return

+     */

+    public static Result<Void> ok() {

+    	return new Result<Void>(null,OK,SUCCESS,null);

+    }

+

+    /**

+     * Create a Status (usually non OK, with a details statement 

+     * @param value

+     * @param status

+     * @param details

+     * @return

+     */

+//    public static<R> Result<R> err(int status, String details) {

+//    	return new Result<R>(null,status,details,null);

+//    }

+    

+    /**

+     * Create a Status (usually non OK, with a details statement and variables supported

+     * @param status

+     * @param details

+     * @param variables

+     * @return

+     */

+    public static<R> Result<R> err(int status, String details, String ... variables) {

+    	return new Result<R>(null,status,details,variables);

+    }

+

+    /**

+     * Create Error from status and Details of previous Result (and not data)

+     * @param pdr

+     * @return

+     */

+    public static<R> Result<R> err(Result<?> pdr) {

+		return new Result<R>(null,pdr.status,pdr.details,pdr.variables);

+	}

+

+    /**

+     * Create General Error from Exception

+     * @param e

+     * @return

+     */

+	public static<R> Result<R> err(Exception e) {

+		return new Result<R>(null,ERR_General,e.getMessage(),EMPTY_VARS);

+	}

+

+	/**

+     * Create a Status (usually non OK, with a details statement 

+     * @param value

+     * @param status

+     * @param details

+     * @return

+     */

+    public static<R> Result<R> create(R value, int status, String details, String ... vars) {

+    	return new Result<R>(value,status,details,vars);

+    }

+

+    /**

+     * Create a Status from a previous status' result/details 

+     * @param value

+     * @param status

+     * @param details

+     * @return

+     */

+    public static<R> Result<R> create(R value, Result<?> result) {

+    	return new Result<R>(value,result.status,result.details,result.variables);

+    }

+

+    private static final int PARTIAL_CONTENT = 0x001;

+    private static final int EMPTY_LIST = 0x002;

+    

+    /**

+	 * AAF Specific problems, etc 

+	 * 

+	 *

+	 */

+

+    /**

+     * specialCondition  is a bit field to enable multiple conditions, e.g. PARTIAL_CONTENT

+     */

+    private      int  specialCondition = 0;

+

+

+    /**

+     * Is result set only partial results, i.e. the DAO clipped the real result set to a smaller number.

+     * @return  true iff result returned PARTIAL_CONTENT

+     */

+    public boolean partialContent() {

+        return (specialCondition & PARTIAL_CONTENT) == PARTIAL_CONTENT;

+    }

+

+    /**

+     * Set fact that result set only returned partial results, i.e. the DAO clipped the real result set to a smaller number.

+     * @param hasPartialContent         set true iff result returned PARTIAL_CONTENT

+     * @return   this Result object, so you can chain calls, in builder style

+     */

+    public Result<RV> partialContent(boolean hasPartialContent) {

+        if (hasPartialContent) {

+	    specialCondition |= PARTIAL_CONTENT;

+	} else {

+	    specialCondition &= (~PARTIAL_CONTENT);

+	}

+        return this;

+    }

+

+    /**

+     * When Result is a List, you can check here to see if it's empty instead of looping

+     * 

+     * @return

+     */

+    public boolean isEmpty() {

+    	return (specialCondition & EMPTY_LIST) == EMPTY_LIST;

+    }

+

+    /**

+     * A common occurrence is that data comes back, but list is empty.  If set, you can skip looking

+     * at list at the outset.

+     * 

+     * @param emptyList

+     * @return

+     */

+    public Result<RV> emptyList(boolean emptyList) {

+    	if (emptyList) {

+    		specialCondition |= EMPTY_LIST;

+    	} else {

+    		specialCondition &= (~EMPTY_LIST);

+    	}

+        return this;

+    }

+

+    

+    /** 

+     * Convenience function.  Checks OK, and also if List is not Empty

+     * Not valid if Data is not a List

+     * @return

+     */

+    public boolean isOK() {

+    	return status == OK;

+    }

+

+    /** 

+     * Convenience function.  Checks OK, and also if List is not Empty

+     * Not valid if Data is not a List

+     * @return

+     */

+    public boolean notOK() {

+    	return status != OK;

+    }

+

+    /** 

+     * Convenience function.  Checks OK, and also if List is not Empty

+     * Not valid if Data is not a List

+     * @return

+     */

+    public boolean isOKhasData() {

+    	return status == OK && (specialCondition & EMPTY_LIST) != EMPTY_LIST;

+    }

+

+

+    /** 

+     * Convenience function.  Checks OK, and also if List is not Empty

+     * Not valid if Data is not a List

+     * @return

+     */

+    public boolean notOKorIsEmpty() {

+    	return status != OK || (specialCondition & EMPTY_LIST) == EMPTY_LIST;

+    }

+

+    @Override

+    public String toString() {

+    	if(status==0) {

+    		return details;

+    	} else {

+	    	StringBuilder sb = new StringBuilder();

+	    	sb.append(status);

+	    	sb.append(':');

+	    	sb.append(String.format(details,((Object[])variables)));

+	    	if(isEmpty()) {

+	    		sb.append("{empty}");

+	    	}

+	    	sb.append('-');

+	    	sb.append(value.toString());

+	    	return sb.toString();

+    	}

+    }

+    

+    public String errorString() {

+    	StringBuilder sb = new StringBuilder();

+    	switch(status) {

+    		case 1: sb.append("Security"); break;

+    		case 2: sb.append("Denied"); break;

+    		case 3: sb.append("Policy"); break;

+    		case 4: sb.append("BadData"); break;

+    		case 5: sb.append("NotImplemented"); break;

+    		case 6: sb.append("NotFound"); break;

+    		case 7: sb.append("AlreadyExists"); break;

+    		case 8: sb.append("ActionNotComplete"); break;

+    		default: sb.append("Error");

+    	}

+    	sb.append(" - ");

+    	sb.append(String.format(details, (Object[])variables));

+    	return sb.toString();

+    }

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/local/AbsData.java b/authz-core/src/main/java/org/onap/aaf/authz/local/AbsData.java
new file mode 100644
index 0000000..30231b8
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/local/AbsData.java
@@ -0,0 +1,215 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.local;

+

+import java.io.File;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.io.RandomAccessFile;

+import java.util.Iterator;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.local.DataFile.Token;

+import org.onap.aaf.authz.local.DataFile.Token.Field;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+

+public abstract class AbsData implements Iterable<String> {

+	protected DataFile data;

+	protected TextIndex ti;

+	private File dataf,idxf,lockf;

+	private String name;

+	private char delim;

+	private int maxLineSize;

+	private int fieldOffset;

+	private int skipLines;

+

+	public AbsData(File dataf,char sepChar, int maxLineSize, int fieldOffset) {

+		File dir = dataf.getParentFile();

+		int dot = dataf.getName().lastIndexOf('.');

+		if(dot>=0) {

+			name = dataf.getName().substring(0,dot);

+		}

+

+		this.dataf=dataf;

+		this.delim = sepChar;

+		this.maxLineSize = maxLineSize;

+		this.fieldOffset = fieldOffset;

+		idxf = new File(dir,name.concat(".idx"));

+		lockf = new File(dir,name.concat(".lock"));

+		

+		

+		data = new DataFile(dataf,"r");

+		ti = new TextIndex(idxf);

+		skipLines=0;

+	}

+	

+	public void skipLines(int lines) {

+		skipLines=lines;

+	}

+	

+	public String name() {

+		return name;

+	}

+	

+	public void open(AuthzTrans trans, long timeout) throws IOException {

+		TimeTaken tt = trans.start("Open Data File", Env.SUB);

+		boolean opened = false, first = true;

+		try {

+				if(!dataf.exists()) {

+					throw new FileNotFoundException("Data File Missing:" + dataf.getCanonicalPath());

+				}

+				long begin = System.currentTimeMillis();

+				long end = begin+timeout;

+				boolean exists;

+				while((exists=lockf.exists()) && begin<end) {

+					if(first) {

+						trans.warn().log("Waiting for",lockf.getCanonicalPath(),"to close");

+						first = false;

+					} 

+					try {

+						Thread.sleep(200);

+					} catch (InterruptedException e) {

+						break;

+					}

+					begin = System.currentTimeMillis();

+				}

+				if(exists) {

+					throw new IOException(lockf.getCanonicalPath() + "exists.  May not open Datafile");

+				}

+				data.open();

+				try {

+					ensureIdxGood(trans);

+				} catch (IOException e) {

+					data.close();

+					throw e;

+				}

+				ti.open();

+				opened = true;

+			

+		} finally {

+			tt.done();

+		}

+		if(!opened) {

+			throw new IOException("DataFile pair for " + name + " was not able to be opened in " + timeout + "ms");

+		}

+	}

+	

+	private synchronized void ensureIdxGood(AuthzTrans trans) throws IOException {

+		if(!idxf.exists() || idxf.length()==0 || dataf.lastModified()>idxf.lastModified()) {

+			trans.warn().log(idxf.getCanonicalPath(),"is missing, empty or out of date, creating");

+			RandomAccessFile raf = new RandomAccessFile(lockf, "rw");

+			try {

+				ti.create(trans, data, maxLineSize, delim, fieldOffset, skipLines);

+				if(!idxf.exists() || (idxf.length()==0 && dataf.length()!=0)) {

+					throw new IOException("Data Index File did not create correctly");

+				}

+			} finally {

+				raf.close();

+				lockf.delete();

+			}

+		}

+	}

+

+	public void close(AuthzTrans trans) throws IOException {

+		ti.close();

+		data.close();

+	}

+	

+	public class Reuse {

+		private Token tokenData;

+		private Field fieldData;

+

+		private Reuse(int size,char delim) {

+			tokenData = data.new Token(size);

+			fieldData = getTokenData().new Field(delim);

+		}

+		

+		public void reset() {

+			getFieldData().reset();

+		}

+

+		public void pos(int rec) {

+			getFieldData().reset();

+			getTokenData().pos(rec);

+		}

+

+		public String next() {

+			return getFieldData().next();

+		}

+		

+		public String at(int field) {

+			return getFieldData().at(field);

+		}

+

+		public String atToEnd(int field) {

+			return getFieldData().atToEnd(field);

+		}

+

+		public Field getFieldData() {

+			return fieldData;

+		}

+

+		public Token getTokenData() {

+			return tokenData;

+		}

+

+	}

+	

+	public Reuse reuse() {

+		return new Reuse(maxLineSize,delim);

+	}

+

+	public Iter iterator() {

+		return new Iter();

+	}

+	

+	public class Iter implements Iterator<String> {

+		private Reuse reuse;

+		private org.onap.aaf.authz.local.TextIndex.Iter tii;

+

+		public Iter() {

+			reuse = reuse();

+			tii = ti.new Iter();

+		}

+

+		@Override

+		public boolean hasNext() {

+			return tii.hasNext();

+		}

+

+		@Override

+		public String next() {

+			reuse.reset();

+			int rec = tii.next();

+			reuse.pos(rec);

+			return reuse.at(0);

+		}

+

+		@Override

+		public void remove() {

+			// read only

+		}

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/local/DataFile.java b/authz-core/src/main/java/org/onap/aaf/authz/local/DataFile.java
new file mode 100644
index 0000000..a027039
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/local/DataFile.java
@@ -0,0 +1,185 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.local;

+

+import java.io.File;

+import java.io.FileNotFoundException;

+import java.io.IOException;

+import java.io.RandomAccessFile;

+import java.nio.ByteBuffer;

+import java.nio.IntBuffer;

+import java.nio.MappedByteBuffer;

+import java.nio.channels.FileChannel;

+import java.nio.channels.FileChannel.MapMode;

+

+public class DataFile {

+	private RandomAccessFile rafile;

+	private FileChannel channel;

+	public MappedByteBuffer mapBuff;

+	private final File file;

+	private final String access;

+	

+	public DataFile(File file, String access)  {

+		this.file = file;

+		this.access = access;

+	}

+	public void open() throws IOException {

+		if(!file.exists()) throw new FileNotFoundException();

+		rafile = new RandomAccessFile(file,access);

+		channel = rafile.getChannel();

+		mapBuff = channel.map("r".equals(access)?MapMode.READ_ONLY:MapMode.READ_WRITE,0,channel.size());

+	}

+	public void close() throws IOException {

+		if(channel!=null){channel.close();}

+		if(rafile!=null) {rafile.close();}

+		mapBuff = null;

+	}

+

+	public long size() throws IOException {

+		return channel.size();

+	}

+

+	private synchronized int load(Token t) {

+		int len = Math.min(mapBuff.limit()-t.next,t.buff.length);

+		if(len>0) {

+			mapBuff.position(t.next);

+			mapBuff.get(t.buff,0,len);

+		}

+		return len<0?0:len;

+	}

+	

+	public class Token {

+		private byte[] buff;

+		int pos, next, end;

+		

+		public Token(int size) {

+			buff = new byte[size];

+			pos = next = end = 0;

+		}

+		

+		public boolean pos(int to) {

+			pos = next = to;

+			return (end=load(this))>0;

+		}

+		

+		public boolean nextLine() {

+			end = load(this);

+			pos = next;

+			for(int i=0;i<end;++i) {

+				if(buff[i]=='\n') {

+					end = i;

+					next += i+1;

+					return true;

+				}

+			}

+			return false;

+		}

+		

+		public IntBuffer getIntBuffer() {

+			return ByteBuffer.wrap(buff).asIntBuffer();

+		}

+

+

+

+		public String toString() {

+			return new String(buff,0,end);

+		}

+		public class Field {

+			char delim;

+			int idx;

+			ByteBuffer bb;

+

+			public Field(char delimiter) {

+				delim = delimiter;

+				idx = 0;

+				bb = null;

+			}

+			

+			public Field reset() {

+				idx = 0;

+				return this;

+			}

+			

+			public String next() {

+				if(idx>=end)return null;

+				int start = idx;

+				byte c=0;

+				int endStr = -1;

+				while(idx<end && idx<buff.length && (c=buff[idx])!=delim && c!='\n') { // for DOS

+					if(c=='\r')endStr=idx;

+					++idx;

+				}

+				

+				if(endStr<0) {

+					endStr=idx-start;

+				} else {

+					endStr=endStr-start;

+				}

+				++idx;

+				return new String(buff,start,endStr);

+			}

+

+			public String at(int fieldOffset) {

+				int start;

+				byte c=0;

+				for(int count = idx = start = 0; idx<end && idx<buff.length; ++idx) {

+					if((c=buff[idx])==delim || c=='\n') {

+						if(count++ == fieldOffset) {

+							break;

+						}

+						start = idx+1;

+					}

+				}

+				return new String(buff,start,(idx-start-(c=='\r'?1:0)));

+			}

+			

+			public String atToEnd(int fieldOffset) {

+				int start;

+				byte c=0;

+				for(int count = idx = start = 0; idx<end && idx<buff.length; ++idx) {

+					if((c=buff[idx])==delim || c=='\n') {

+						if(count++ == fieldOffset) {

+							break;

+						}

+						start = idx+1;

+					}

+				}

+				

+				for(; idx<end && idx<buff.length && (c=buff[idx])!='\n'; ++idx) {

+					++idx;

+				}

+				return new String(buff,start,(idx-start-((c=='\r' || idx>=end)?1:0)));

+			}

+

+		}

+

+		public int pos() {

+			return pos;

+		}

+	}

+

+	public File file() {

+		return file;

+	}

+	

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/local/TextIndex.java b/authz-core/src/main/java/org/onap/aaf/authz/local/TextIndex.java
new file mode 100644
index 0000000..cb339a4
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/local/TextIndex.java
@@ -0,0 +1,253 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.local;

+

+import java.io.File;

+import java.io.IOException;

+import java.io.RandomAccessFile;

+import java.nio.ByteBuffer;

+import java.nio.IntBuffer;

+import java.nio.channels.FileChannel;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.LinkedList;

+import java.util.List;

+

+import org.onap.aaf.authz.local.DataFile.Token;

+import org.onap.aaf.authz.local.DataFile.Token.Field;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+public class TextIndex {

+	private static final int REC_SIZE=8;

+	

+	private File file;

+	private DataFile dataFile=null;

+	

+	public TextIndex(File theFile) {

+		file = theFile;

+	}

+	

+	public void open() throws IOException {

+		dataFile = new DataFile(file,"r");

+		dataFile.open();

+	}

+	

+	public void close() throws IOException {

+		if(dataFile!=null) {dataFile.close();}

+	}

+

+	public int find(Object key, AbsData.Reuse reuse, int offset) throws IOException {

+		return find(key,reuse.getTokenData(),reuse.getFieldData(),offset);

+	}

+	

+	public int find(Object key, DataFile.Token dtok, Field df, int offset) throws IOException {

+		if(dataFile==null) {throw new IOException("File not opened");}

+		long hash = hashToLong(key.hashCode());

+		int min=0, max = (int)(dataFile.size()/REC_SIZE);

+		Token ttok = dataFile.new Token(REC_SIZE);

+		IntBuffer tib = ttok.getIntBuffer();

+		long lhash;

+		int curr;

+		while((max-min)>100) {

+			ttok.pos((curr=(min+(max-min)/2))*REC_SIZE);

+			tib.rewind();

+			lhash = hashToLong(tib.get());

+			if(lhash<hash) {

+				min=curr+1;

+			} else if(lhash>hash) {

+				max=curr-1;

+			} else {

+				min=curr-40;

+				max=curr+40;

+				break;

+			}

+		}

+		

+		List<Integer> entries = new ArrayList<Integer>();

+		for(int i=min;i<=max;++i) {

+			ttok.pos(i*REC_SIZE);

+			tib.rewind();

+			lhash = hashToLong(tib.get());

+			if(lhash==hash) {

+				entries.add(tib.get());

+			} else if(lhash>hash) {

+				break;

+			}

+		}

+		

+		for(Integer i : entries) {

+			dtok.pos(i);

+			if(df.at(offset).equals(key)) {

+				return i;

+			}

+		}

+		return -1;

+	}

+	

+

+	/*

+	 * Have to change Bytes into a Long, to avoid the inevitable signs in the Hash

+	 */

+	private static long hashToLong(int hash) {

+		long rv;

+		if(hash<0) {

+			rv = 0xFFFFFFFFL & hash;

+		} else {

+			rv = hash;

+		}

+		return rv;

+	}

+	

+	public void create(final Trans trans,final DataFile data, int maxLine, char delim, int fieldOffset, int skipLines) throws IOException {

+		RandomAccessFile raf;

+		FileChannel fos;

+		

+		List<Idx> list = new LinkedList<Idx>(); // Some hashcodes will double... DO NOT make a set

+		TimeTaken tt2 = trans.start("Open Files", Env.SUB);

+		try {

+			raf = new RandomAccessFile(file,"rw");

+			raf.setLength(0L);

+			fos = raf.getChannel();

+		} finally {

+			tt2.done();

+		}

+		

+		try {

+			

+			Token t = data.new Token(maxLine);  

+			Field f = t.new Field(delim);

+			

+			int count = 0;

+			if(skipLines>0) {

+				trans.info().log("Skipping",skipLines,"line"+(skipLines==1?" in":"s in"),data.file().getName());

+			}

+			for(int i=0;i<skipLines;++i) {

+				t.nextLine();

+			}

+			tt2 = trans.start("Read", Env.SUB);

+			try {

+				while(t.nextLine()) {

+					list.add(new Idx(f.at(fieldOffset),t.pos()));

+					++count;

+				}

+			} finally {

+				tt2.done();

+			}

+			trans.checkpoint("    Read " + count + " records");

+			tt2 = trans.start("Sort List", Env.SUB);

+			Collections.sort(list);

+			tt2.done();

+			tt2 = trans.start("Write Idx", Env.SUB);

+			try {

+				ByteBuffer bb = ByteBuffer.allocate(8*1024);

+				IntBuffer ib = bb.asIntBuffer();

+				for(Idx idx : list) {

+					if(!ib.hasRemaining()) {

+						fos.write(bb);

+						ib.clear();

+						bb.rewind();

+					}

+					ib.put(idx.hash);

+					ib.put(idx.pos);

+				}

+				bb.limit(4*ib.position());

+				fos.write(bb);

+			} finally {

+				tt2.done();

+			}

+		} finally {

+			fos.close();

+			raf.close();

+		}

+	}

+	

+	public class Iter {

+		private int idx;

+		private Token t;

+		private long end;

+		private IntBuffer ib;

+

+

+		public Iter() {

+			try {

+				idx = 0;

+				end = dataFile.size();

+				t  = dataFile.new Token(REC_SIZE);

+				ib = t.getIntBuffer();

+

+			} catch (IOException e) {

+				end = -1L;

+			}

+		}

+		

+		public int next() {

+			t.pos(idx);

+			ib.clear();

+			ib.get();

+			int rec = ib.get();

+			idx += REC_SIZE;

+			return rec;

+		}

+

+		public boolean hasNext() {

+			return idx<end;

+		}

+	}

+	

+	private static class Idx implements Comparable<Idx> {

+		public int hash, pos;

+		public Idx(Object obj, int pos) {

+			hash = obj.hashCode();

+			this.pos = pos;

+		}

+		

+		@Override

+		public int compareTo(Idx ib) {

+			long a = hashToLong(hash);

+			long b = hashToLong(ib.hash);

+			return a>b?1:a<b?-1:0;

+		}

+

+		/* (non-Javadoc)

+		 * @see java.lang.Object#equals(java.lang.Object)

+		 */

+		@Override

+		public boolean equals(Object o) {

+			if(o!=null && o instanceof Idx) {

+				return hash == ((Idx)o).hash;

+			}

+			return false;

+		}

+

+		/* (non-Javadoc)

+		 * @see java.lang.Object#hashCode()

+		 */

+		@Override

+		public int hashCode() {

+			return hash;

+		}

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/org/EmailWarnings.java b/authz-core/src/main/java/org/onap/aaf/authz/org/EmailWarnings.java
new file mode 100644
index 0000000..857a953
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/org/EmailWarnings.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+public interface EmailWarnings

+{

+    public long credExpirationWarning();

+    public long roleExpirationWarning();

+    public long credEmailInterval();

+    public long roleEmailInterval();

+    public long apprEmailInterval();

+    public long emailUrgentWarning();

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/org/Executor.java b/authz-core/src/main/java/org/onap/aaf/authz/org/Executor.java
new file mode 100644
index 0000000..14718f7
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/org/Executor.java
@@ -0,0 +1,35 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+public interface Executor {

+	// remove User from user/Role

+	// remove user from Admins

+	// if # of Owners > 1, remove User from Owner

+	// if # of Owners = 1, changeOwner to X  Remove Owner????

+	boolean hasPermission(String user, String ns, String type, String instance, String action); 

+	boolean inRole(String name);

+	

+	public String namespace() throws Exception;

+	public String id();

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/org/Organization.java b/authz-core/src/main/java/org/onap/aaf/authz/org/Organization.java
new file mode 100644
index 0000000..2ed4d37
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/org/Organization.java
@@ -0,0 +1,490 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+

+/**

+ * Organization

+ * 

+ * There is Organizational specific information required which we have extracted to a plugin

+ * 

+ * It supports using Company Specific User Directory lookups, as well as supporting an

+ * Approval/Validation Process to simplify control of Roles and Permissions for large organizations

+ * in lieu of direct manipulation by a set of Admins. 

+ *  

+ *

+ */

+public interface Organization {

+	public static final String N_A = "n/a";

+

+	public interface Identity {

+		public String id();

+		public String fullID();					// Fully Qualified ID (includes Domain of Organization)

+		public String type(); 					// Must be one of "IdentityTypes", see below

+		public String responsibleTo(); 	        // Chain of Command, Comma Separated if required

+		public List<String> delegate(); 		// Someone who has authority to act on behalf of Identity

+		public String email();

+		public String fullName();

+		public boolean isResponsible();			// Is id passed belong to a person suitable to be Responsible for content Management

+		public boolean isFound();				// Is Identity found in Identity stores

+		public Identity owner() throws OrganizationException;					// Identity is directly responsible for App ID

+		public Organization org(); 				// Organization of Identity

+	}

+

+

+	/**

+	 * Name of Organization, suitable for Logging

+	 * @return

+	 */

+	public String getName();

+

+	/**

+	 * Realm, for use in distinguishing IDs from different systems/Companies

+	 * @return

+	 */

+	public String getRealm();

+

+	String getDomain();

+

+	/**

+	 * Get Identity information based on userID

+	 * 

+	 * @param id

+	 * @return

+	 */

+	public Identity getIdentity(AuthzTrans trans, String id) throws OrganizationException;

+	

+

+	/**

+	 * Does the ID pass Organization Standards

+	 * 

+	 * Return a Blank (empty) String if empty, otherwise, return a "\n" separated list of 

+	 * reasons why it fails

+	 * 

+	 * @param id

+	 * @return

+	 */

+	public String isValidID(String id);

+

+	/**

+	 * Return a Blank (empty) String if empty, otherwise, return a "\n" separated list of 

+	 * reasons why it fails

+	 *  

+	 *  Identity is passed in to allow policies regarding passwords that are the same as user ID

+	 *  

+	 *  any entries for "prev" imply a reset

+	 *  

+	 * @param id

+	 * @param password

+	 * @return

+	 */

+	public String isValidPassword(String user, String password, String ... prev);

+

+

+	/**

+	 * Does your Company distinguish essential permission structures by kind of Identity?

+	 * i.e. Employee, Contractor, Vendor 

+	 * @return

+	 */

+	public Set<String> getIdentityTypes();

+

+	public enum Notify {

+		Approval(1),

+		PasswordExpiration(2),

+        RoleExpiration(3);

+

+		final int id;

+		Notify(int id) {this.id = id;}

+		public int getValue() {return id;}

+		public static Notify from(int type) {

+			for(Notify t : Notify.values()) {

+				if(t.id==type) {

+					return t;

+				}

+			}

+			return null;

+		}

+	}

+

+	public enum Response{

+		OK,

+		ERR_NotImplemented,

+		ERR_UserNotExist,

+		ERR_NotificationFailure,

+		};

+		

+	public enum Expiration {

+		Password,

+		TempPassword, 

+		Future,

+		UserInRole,

+		UserDelegate, 

+		ExtendPassword

+	}

+	

+	public enum Policy {

+		CHANGE_JOB, 

+		LEFT_COMPANY, 

+		CREATE_MECHID, 

+		CREATE_MECHID_BY_PERM_ONLY,

+		OWNS_MECHID,

+		AS_EMPLOYEE, 

+		MAY_EXTEND_CRED_EXPIRES

+	}

+	

+	/**

+	 * Notify a User of Action or Info

+	 * 

+	 * @param type

+	 * @param url

+	 * @param users (separated by commas)

+	 * @param ccs (separated by commas)

+	 * @param summary

+	 */

+

+    public Response notify(AuthzTrans trans, Notify type, String url, String ids[], String ccs[], String summary, Boolean urgent);

+

+	/**

+	 * (more) generic way to send an email

+	 * 

+	 * @param toList

+	 * @param ccList

+	 * @param subject

+	 * @param body

+	 * @param urgent

+	 */

+

+	public int sendEmail(AuthzTrans trans, List<String> toList, List<String> ccList, String subject, String body, Boolean urgent) throws OrganizationException;

+

+	/**

+	 * whenToValidate

+	 * 

+	 * Authz support services will ask the Organization Object at startup when it should

+	 * kickoff Validation processes given particular types. 

+	 * 

+	 * This allows the Organization to express Policy

+	 * 

+	 * Turn off Validation behavior by returning "null"

+	 * 

+	 */

+	public Date whenToValidate(Notify type, Date lastValidated);

+

+	

+	/**

+	 * Expiration

+	 * 

+	 * Given a Calendar item of Start (or now), set the Expiration Date based on the Policy

+	 * based on type.

+	 * 

+	 * For instance, "Passwords expire in 3 months"

+	 * 

+	 * The Extra Parameter is used by certain Orgs.

+	 * 

+	 * For Password, the extra is UserID, so it can check the Identity Type

+	 * 

+	 * @param gc

+	 * @param exp

+	 * @return

+	 */

+	public GregorianCalendar expiration(GregorianCalendar gc, Expiration exp, String ... extra);

+	

+	/**

+	 * Get Email Warning timing policies

+	 * @return

+	 */

+	public EmailWarnings emailWarningPolicy();

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public List<Identity> getApprovers(AuthzTrans trans, String user) throws OrganizationException ;

+	

+	/*

+	 * 

+	 * @param user

+	 * @param type

+	 * @param users

+	 * @return

+	public Response notifyRequest(AuthzTrans trans, String user, Approval type, List<User> approvers);

+	*/

+	

+	/**

+	 * 

+	 * @return

+	 */

+	public String getApproverType();

+

+	/*

+	 * startOfDay - define for company what hour of day business starts (specifically for password and other expiration which

+	 *   were set by Date only.)

+	 *    

+	 * @return

+	 */

+	public int startOfDay();

+

+    /**

+     * implement this method to support any IDs that can have multiple entries in the cred table

+     * NOTE: the combination of ID/expiration date/(encryption type when implemented) must be unique.

+     * 		 Since expiration date is based on startOfDay for your company, you cannot create many

+     * 		 creds for the same ID in the same day.

+     * @param id

+     * @return

+     */

+    public boolean canHaveMultipleCreds(String id);

+    

+    /**

+     * 

+     * @param id

+     * @return

+     */

+    public boolean isValidCred(String id);

+    

+    /**

+     * If response is Null, then it is valid.  Otherwise, the Organization specific reason is returned.

+     *  

+     * @param trans

+     * @param policy

+     * @param executor

+     * @param vars

+     * @return

+     * @throws OrganizationException

+     */

+    public String validate(AuthzTrans trans, Policy policy, Executor executor, String ... vars) throws OrganizationException;

+

+	boolean isTestEnv();

+

+	public void setTestMode(boolean dryRun);

+

+	public static final Organization NULL = new Organization() 

+	{

+		private final GregorianCalendar gc = new GregorianCalendar(1900, 1, 1);

+		private final List<Identity> nullList = new ArrayList<Identity>();

+		private final Set<String> nullStringSet = new HashSet<String>();

+		private final Identity nullIdentity = new Identity() {

+			List<String> nullIdentity = new ArrayList<String>();

+			@Override

+			public String type() {

+				return N_A;

+			}

+			@Override

+			public String responsibleTo() {

+				return N_A;

+			}

+			@Override

+			public boolean isResponsible() {

+				return false;

+			}

+			

+			@Override

+			public boolean isFound() {

+				return false;

+			}

+			

+			@Override

+			public String id() {

+				return N_A;

+			}

+			

+			@Override

+			public String fullID() {

+				return N_A;

+			}

+			

+			@Override

+			public String email() {

+				return N_A;

+			}

+			

+			@Override

+			public List<String> delegate() {

+				return nullIdentity;

+			}

+			@Override

+			public String fullName() {

+				return N_A;

+			}

+			@Override

+			public Identity owner() {

+				return null;

+			}

+			@Override

+			public Organization org() {

+				return NULL;

+			}

+		};

+

+		@Override

+		public String getName() {

+			return N_A;

+		}

+	

+		@Override

+		public String getRealm() {

+			return N_A;

+		}

+	

+		@Override

+		public String getDomain() {

+			return N_A;

+		}

+	

+		@Override

+		public Identity getIdentity(AuthzTrans trans, String id) {

+			return nullIdentity;

+		}

+	

+		@Override

+		public String isValidID(String id) {

+			return N_A;

+		}

+	

+		@Override

+		public String isValidPassword(String user, String password,String... prev) {

+			return N_A;

+		}

+	

+		@Override

+		public Set<String> getIdentityTypes() {

+			return nullStringSet;

+		}

+	

+		@Override

+		public Response notify(AuthzTrans trans, Notify type, String url,

+				String[] users, String[] ccs, String summary, Boolean urgent) {

+			return Response.ERR_NotImplemented;

+		}

+	

+		@Override

+		public int sendEmail(AuthzTrans trans, List<String> toList, List<String> ccList,

+				String subject, String body, Boolean urgent) throws OrganizationException {

+			return 0;

+		}

+	

+		@Override

+		public Date whenToValidate(Notify type, Date lastValidated) {

+			return gc.getTime();

+		}

+	

+		@Override

+		public GregorianCalendar expiration(GregorianCalendar gc,

+				Expiration exp, String... extra) {

+			return gc==null?new GregorianCalendar():gc;

+		}

+	

+		@Override

+		public List<Identity> getApprovers(AuthzTrans trans, String user)

+				throws OrganizationException {

+			return nullList;

+		}

+	

+		@Override

+		public String getApproverType() {

+			return "";

+		}

+	

+		@Override

+		public int startOfDay() {

+			return 0;

+		}

+	

+		@Override

+		public boolean canHaveMultipleCreds(String id) {

+			return false;

+		}

+	

+		@Override

+		public boolean isValidCred(String id) {

+			return false;

+		}

+	

+		@Override

+		public String validate(AuthzTrans trans, Policy policy, Executor executor, String ... vars)

+				throws OrganizationException {

+			return "Null Organization rejects all Policies";

+		}

+	

+		@Override

+		public boolean isTestEnv() {

+			return false;

+		}

+	

+		@Override

+		public void setTestMode(boolean dryRun) {

+		}

+

+		@Override

+		public EmailWarnings emailWarningPolicy() {

+			return new EmailWarnings() {

+

+				@Override

+			    public long credEmailInterval()

+			    {

+			        return 604800000L; // 7 days in millis 1000 * 86400 * 7

+			    }

+			    

+				@Override

+			    public long roleEmailInterval()

+			    {

+			        return 604800000L; // 7 days in millis 1000 * 86400 * 7

+			    }

+				

+				@Override

+				public long apprEmailInterval() {

+			        return 259200000L; // 3 days in millis 1000 * 86400 * 3

+				}

+			    

+				@Override

+			    public long  credExpirationWarning()

+			    {

+			        return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30  in milliseconds

+			    }

+			    

+				@Override

+			    public long roleExpirationWarning()

+			    {

+			        return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30  in milliseconds

+			    }

+

+				@Override

+			    public long emailUrgentWarning()

+			    {

+			        return( 1209600000L ); // Two weeks, in milliseconds 1000 * 86400 * 14  in milliseconds

+			    }

+

+			};

+		}

+	};

+}

+

+

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationException.java b/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationException.java
new file mode 100644
index 0000000..fa23a4c
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationException.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+public class OrganizationException extends Exception {

+

+	/**

+	 * 

+	 */

+	private static final long serialVersionUID = 1L;

+

+	public OrganizationException() {

+		super();

+	}

+

+	public OrganizationException(String message) {

+		super(message);

+	}

+

+	public OrganizationException(Throwable cause) {

+		super(cause);

+	}

+

+	public OrganizationException(String message, Throwable cause) {

+		super(message, cause);

+	}

+

+	public OrganizationException(String message, Throwable cause, boolean enableSuppression,

+			boolean writableStackTrace) {

+		super(message, cause, enableSuppression, writableStackTrace);

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationFactory.java b/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationFactory.java
new file mode 100644
index 0000000..653e927
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/org/OrganizationFactory.java
@@ -0,0 +1,148 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+import java.lang.reflect.Constructor;

+import java.lang.reflect.InvocationTargetException;

+import java.util.Map;

+import java.util.concurrent.ConcurrentHashMap;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Slot;

+

+/**

+ * Organization Plugin Mechanism

+ * 

+ * Define a NameSpace for the company (i.e. com.att), and put in Properties as 

+ * "Organization.[your NS" and assign the supporting Class.  

+ * 

+ * Example:

+ * Organization.com.att=org.onap.aaf.authz.org.att.ATT

+ *

+ *

+ */

+public class OrganizationFactory {

+	public static final String ORG_SLOT = "ORG_SLOT";

+	private static Organization defaultOrg = null;

+	private static Map<String,Organization> orgs = new ConcurrentHashMap<String,Organization>();

+	private static Slot orgSlot;

+	

+	public static void setDefaultOrg(AuthzEnv env, String orgClass) throws APIException {

+		orgSlot = env.slot(ORG_SLOT);

+		try {

+			@SuppressWarnings("unchecked")

+			Class<Organization> cls = (Class<Organization>) Class.forName(orgClass);

+			Constructor<Organization> cnst = cls.getConstructor(AuthzEnv.class);

+			defaultOrg = cnst.newInstance(env);

+		} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | 

+				InstantiationException | IllegalAccessException | IllegalArgumentException | 

+				InvocationTargetException e) {

+			throw new APIException(e);

+		}

+	}

+	

+	public static Organization obtain(AuthzEnv env,String orgNS) throws OrganizationException {

+		int at = orgNS.indexOf('@');

+		if(at<0) {

+			if(!orgNS.startsWith("com.")) {

+				int dot1;

+				if((dot1 = orgNS.lastIndexOf('.'))>-1) {

+					int dot2;

+					StringBuilder sb = new StringBuilder();

+					if((dot2 = orgNS.lastIndexOf('.',dot1-1))>-1) {

+						sb.append(orgNS,dot1+1,orgNS.length());

+						sb.append('.');

+						sb.append(orgNS,dot2+1,dot1);

+					} else {

+						sb.append(orgNS,dot1+1,orgNS.length());

+						sb.append('.');

+						sb.append(orgNS,at+1,dot1);

+					}

+					orgNS=sb.toString();

+				}

+			}

+		} else {

+			// Only use two places (Enterprise) of domain

+			int dot;

+			if((dot= orgNS.lastIndexOf('.'))>-1) {

+				StringBuilder sb = new StringBuilder();

+				int dot2;

+				if((dot2 = orgNS.lastIndexOf('.',dot-1))>-1) {

+					sb.append(orgNS.substring(dot+1));

+					sb.append(orgNS.subSequence(dot2, dot));

+					orgNS = sb.toString();

+				} else {

+					sb.append(orgNS.substring(dot+1));

+					sb.append('.');

+					sb.append(orgNS.subSequence(at+1, dot));

+					orgNS = sb.toString();

+				}

+			}

+		}

+		Organization org = orgs.get(orgNS);

+		if(org == null) {

+			String orgClass = env.getProperty("Organization."+orgNS);

+			if(orgClass == null) {

+				env.warn().log("There is no Organization." + orgNS + " property");

+			} else {

+				for(Organization o : orgs.values()) {

+					if(orgClass.equals(o.getClass().getName())) {

+						org = o;

+					}

+				}

+				if(org==null) {

+					try {

+						@SuppressWarnings("unchecked")

+						Class<Organization> cls = (Class<Organization>) Class.forName(orgClass);

+						Constructor<Organization> cnst = cls.getConstructor(AuthzEnv.class);

+						org = cnst.newInstance(env);

+					} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | 

+							InstantiationException | IllegalAccessException | IllegalArgumentException | 

+							InvocationTargetException e) {

+						throw new OrganizationException(e);

+					}

+				}

+				orgs.put(orgNS, org);

+			}

+			if(org==null && defaultOrg!=null) {

+				org=defaultOrg;

+				orgs.put(orgNS, org);

+			}

+		}

+		

+		return org;

+	}

+

+	public static void set(AuthzTrans trans, String orgNS) throws OrganizationException {

+		Organization org = obtain(trans.env(),orgNS);

+		trans.put(orgSlot, org);

+	}

+	

+	public static Organization get(AuthzTrans trans) {

+		return trans.get(orgSlot,defaultOrg);

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/authz/server/AbsServer.java b/authz-core/src/main/java/org/onap/aaf/authz/server/AbsServer.java
new file mode 100644
index 0000000..3ad45f5
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/authz/server/AbsServer.java
@@ -0,0 +1,150 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.server;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.lang.reflect.Constructor;

+import java.net.URL;

+import java.security.GeneralSecurityException;

+import java.security.Principal;

+import java.util.Properties;

+

+import javax.net.ssl.SSLContext;

+import javax.net.ssl.SSLSocketFactory;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.cssa.rserv.RServlet;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+//import org.onap.aaf.cadi.PropAccess;

+import org.onap.aaf.cadi.aaf.v2_0.AAFConHttp;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.cadi.http.HTransferSS;

+import org.onap.aaf.inno.env.APIException;

+

+public abstract class AbsServer extends RServlet<AuthzTrans> {

+	private static final String AAF_API_VERSION = "2.0";

+	public final String app;

+	public final AuthzEnv env;

+	public AAFConHttp aafCon;

+

+    public AbsServer(final AuthzEnv env, final String app) throws CadiException, GeneralSecurityException, IOException {

+    	this.env = env;

+    	this.app = app;

+    	if(env.getProperty(Config.AAF_URL)!=null) {

+    		//aafCon = new AAFConHttp(env);

+    	}

+    }

+    

+    // This is a method, so we can overload for AAFAPI

+    public String aaf_url() {

+    	return env.getProperty(Config.AAF_URL);

+    }

+    

+	public abstract void startDME2(Properties props) throws Exception;

+	public static void setup(Class<?> abss, String propFile) {

+

+		try {

+			// Load Properties from authFramework.properties.  Needed for DME2 and AuthzEnv

+			Properties props = new Properties();

+			URL rsrc = ClassLoader.getSystemResource(propFile);

+			if(rsrc==null) {

+				System.err.println("Folder containing " + propFile + " must be on Classpath");

+				System.exit(1);

+			}

+

+			InputStream is = rsrc.openStream();

+			try {

+				props.load(is);

+			} finally {

+				is.close();

+				is=null;

+			}

+

+			// Load Properties into AuthzEnv

+			AuthzEnv env = new AuthzEnv(props);

+			// Log where Config found

+			env.init().log("Configuring from",rsrc.getPath());

+			rsrc = null;

+			

+			// Print Cipher Suites Available

+			if(env.debug().isLoggable()) {

+				SSLContext context = SSLContext.getDefault();

+				SSLSocketFactory sf = context.getSocketFactory();

+				StringBuilder sb = new StringBuilder("Available Cipher Suites: ");

+				boolean first = true;

+				int count=0;

+				for( String cs : sf.getSupportedCipherSuites()) {

+					if(first)first = false;

+					else sb.append(',');

+					sb.append(cs);

+					if(++count%4==0){sb.append('\n');}

+				}

+				env.debug().log(sb);

+			}

+

+			// Set ROOT NS, etc

+			Define.set(env);

+

+			// Convert CADI properties and Encrypted Passwords for these two properties (if exist) 

+			// to DME2 Readable.  Further, Discovery Props are loaded to System if missing.

+			// May be causing client errors

+			//Config.cadiToDME2(env,props);

+			env.init().log("DME2 ServiceName: " + env.getProperty("DMEServiceName","unknown"));

+

+			// Construct with Env

+			Constructor<?> cons = abss.getConstructor(new Class<?>[] {AuthzEnv.class});

+			// Start DME2 (DME2 needs Properties form of props)

+			AbsServer s = (AbsServer)cons.newInstance(env);

+			

+			// Schedule removal of Clear Text Passwords from System Props (DME2 Requirement) 

+//			new Timer("PassRemove").schedule(tt, 120000);

+//			tt=null;

+			

+			s.startDME2(props);

+		} catch (Exception e) {

+			e.printStackTrace(System.err);

+			System.exit(1);

+		}

+	}

+	

+	public Rcli<?> client() throws CadiException {

+		return aafCon.client(AAF_API_VERSION);

+	}

+

+	public Rcli<?> clientAsUser(Principal p) throws CadiException {

+		return aafCon.client(AAF_API_VERSION).forUser(

+				new HTransferSS(p,app, aafCon.securityInfo()));

+	}

+

+	public<RET> RET clientAsUser(Principal p,Retryable<RET> retryable) throws APIException, LocatorException, CadiException  {

+			return aafCon.hman().best(new HTransferSS(p,app, aafCon.securityInfo()), retryable);

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cache/Cache.java b/authz-core/src/main/java/org/onap/aaf/cache/Cache.java
new file mode 100644
index 0000000..3434ca7
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cache/Cache.java
@@ -0,0 +1,195 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cache;

+

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.Timer;

+import java.util.TimerTask;

+import java.util.concurrent.ConcurrentHashMap;

+import java.util.logging.Level;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * Create and maintain a Map of Maps used for Caching

+ * 

+ *

+ * @param <TRANS>

+ * @param <DATA>

+ */

+public class Cache<TRANS extends Trans, DATA> {

+	private static Clean clean;

+	private static Timer cleanseTimer;

+

+	public static final String CACHE_HIGH_COUNT = "CACHE_HIGH_COUNT";

+	public static final String CACHE_CLEAN_INTERVAL = "CACHE_CLEAN_INTERVAL";

+//	public static final String CACHE_MIN_REFRESH_INTERVAL = "CACHE_MIN_REFRESH_INTERVAL";

+

+	private static final Map<String,Map<String,Dated>> cacheMap;

+

+	static {

+		cacheMap = new HashMap<String,Map<String,Dated>>();

+	}

+

+	/**

+	 * Dated Class - store any Data with timestamp

+	 * 

+	 *

+	 */

+	public final static class Dated { 

+		public Date timestamp;

+		public List<?> data;

+		

+		public Dated(List<?> data) {

+			timestamp = new Date();

+			this.data = data;

+		}

+

+		public <T> Dated(T t) {

+			timestamp = new Date();

+			ArrayList<T> al = new ArrayList<T>(1);

+			al.add(t);

+			data = al;

+		}

+

+		public void touch() {

+			timestamp = new Date();

+		}

+	}

+	

+	public static Map<String,Dated> obtain(String key) {

+		Map<String, Dated> m = cacheMap.get(key);

+		if(m==null) {

+			m = new ConcurrentHashMap<String, Dated>();

+			synchronized(cacheMap) {

+				cacheMap.put(key, m);

+			}

+		}

+		return m;

+	}

+

+	/**

+	 * Clean will examine resources, and remove those that have expired.

+	 * 

+	 * If "highs" have been exceeded, then we'll expire 10% more the next time.  This will adjust after each run

+	 * without checking contents more than once, making a good average "high" in the minimum speed.

+	 * 

+	 *

+	 */

+	private final static class Clean extends TimerTask {

+		private final Env env;

+		private Set<String> set;

+		

+		// The idea here is to not be too restrictive on a high, but to Expire more items by 

+		// shortening the time to expire.  This is done by judiciously incrementing "advance"

+		// when the "highs" are exceeded.  This effectively reduces numbers of cached items quickly.

+		private final int high;

+		private long advance;

+		private final long timeInterval;

+		

+		public Clean(Env env, long cleanInterval, int highCount) {

+			this.env = env;

+			high = highCount;

+			timeInterval = cleanInterval;

+			advance = 0;

+			set = new HashSet<String>();

+		}

+		

+		public synchronized void add(String key) {

+			set.add(key);

+		}

+

+		public void run() {

+			int count = 0;

+			int total = 0;

+			// look at now.  If we need to expire more by increasing "now" by "advance"

+			Date now = new Date(System.currentTimeMillis() + advance);

+			

+			

+			for(String name : set) {

+				Map<String,Dated> map = cacheMap.get(name);

+				if(map!=null) for(Map.Entry<String,Dated> me : map.entrySet()) {

+					++total;

+					if(me.getValue().timestamp.before(now)) {

+						map.remove(me.getKey());

+						++count;

+					}

+				}

+//				if(count>0) {

+//					env.info().log(Level.INFO, "Cache removed",count,"expired",name,"Elements");

+//				}

+			}

+			

+			if(count>0) {

+				env.info().log(Level.INFO, "Cache removed",count,"expired Cached Elements out of", total);

+			}

+

+			// If High (total) is reached during this period, increase the number of expired services removed for next time.

+			// There's no point doing it again here, as there should have been cleaned items.

+			if(total>high) {

+				// advance cleanup by 10%, without getting greater than timeInterval.

+				advance = Math.min(timeInterval, advance+(timeInterval/10));

+			} else {

+				// reduce advance by 10%, without getting lower than 0.

+				advance = Math.max(0, advance-(timeInterval/10));

+			}

+		}

+	}

+

+	public static synchronized void startCleansing(Env env, String ... keys) {

+		if(cleanseTimer==null) {

+			cleanseTimer = new Timer("Cache Cleanup Timer");

+			int cleanInterval = Integer.parseInt(env.getProperty(CACHE_CLEAN_INTERVAL,"60000")); // 1 minute clean cycles 

+			int highCount = Integer.parseInt(env.getProperty(CACHE_HIGH_COUNT,"5000"));

+			cleanseTimer.schedule(clean = new Clean(env, cleanInterval, highCount), cleanInterval, cleanInterval);

+		}

+		

+		for(String key : keys) {

+			clean.add(key);

+		}

+	}

+

+	public static void stopTimer() {

+		if(cleanseTimer!=null) {

+			cleanseTimer.cancel();

+			cleanseTimer = null;

+		}

+	}

+

+	public static void addShutdownHook() {

+		Runtime.getRuntime().addShutdownHook(new Thread() {

+			@Override

+			public void run() {

+				Cache.stopTimer();

+			}

+		}); 

+	}

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Acceptor.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Acceptor.java
new file mode 100644
index 0000000..bfc2d37
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Acceptor.java
@@ -0,0 +1,169 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * Find Acceptable Paths and place them where TypeCode can evaluate.

+ * 

+ * If there are more than one, TypeCode will choose based on "q" value

+ *

+ * @param <TRANS>

+ */

+class Acceptor<TRANS extends Trans>  {

+	private List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> types;

+	List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> acceptable;

+	

+	public Acceptor(List<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>> types) {

+		this.types = types;

+		acceptable = new ArrayList<Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>>>();

+	}

+	

+	private boolean eval(HttpCode<TRANS,?> code, String str, List<String> props) {

+//		int plus = str.indexOf('+');

+//		if(plus<0) {

+		boolean ok = false;

+		boolean any = false;

+		for(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type : types) {

+			ok = true;

+			if(type.x.equals(str)) {

+				for(Iterator<String> iter = props.iterator();ok && iter.hasNext();) {

+					ok = props(type,iter.next(),iter.next());

+				}

+				if(ok) {

+					any = true;

+					acceptable.add(type);

+				}

+			}

+		}

+//		} else { // Handle Accepts with "+" as in application/xaml+xml

+//			int prev = str.indexOf('/')+1;

+//			String first = str.substring(0,prev);

+//			String nstr;

+//			while(prev!=0) {

+//				nstr = first + (plus<0?str.substring(prev):str.substring(prev,plus));

+//				

+//				for(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type : types) {

+//					if(type.x.equals(nstr)) {

+//						acceptable.add(type);

+//						return type;

+//					}

+//				}

+//				prev = plus+1;

+//				plus=str.indexOf('+', prev);

+//			};

+//		}

+		return any;

+	}

+

+	/**

+	 * Evaluate Properties

+	 * @param type

+	 * @param tag

+	 * @param value

+	 * @return

+	 */

+	private boolean props(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type, String tag, String value) {

+		boolean rv = false;

+		if(type.y!=null) {

+			for(Pair<String,Object> prop : type.y.y){

+				if(tag.equals(prop.x)) {

+					if(tag.equals("charset")) {

+						return prop.x==null?false:prop.y.equals(value.toLowerCase()); // return True if Matched

+					} else if(tag.equals("version")) {

+						return prop.y.equals(new Version(value)); // Note: Version Class knows Minor Version encoding

+					} else if(tag.equals(Content.Q)) { // replace Q value

+						try {

+							type.y.y.get(0).y=Float.parseFloat(value);

+						} catch (NumberFormatException e) {

+							rv=false; // need to do something to make Sonar happy. But nothing to do.

+						}

+						return true;

+					} else {

+						return value.equals(prop.y);

+					}

+				}

+			}

+		}

+		return rv;

+	}

+

+	/**

+	 * parse 

+	 * 

+	 * Note: I'm processing by index to avoid lots of memory creation, which speeds things

+	 * up for this time critical section of code. 

+	 * @param code

+	 * @param cntnt

+	 * @return

+	 */

+	protected boolean parse(HttpCode<TRANS, ?> code, String cntnt) {

+		byte bytes[] = cntnt.getBytes();

+		

+		int cis,cie=-1,cend;

+		int sis,sie,send;

+		String name;

+		ArrayList<String> props = new ArrayList<String>();

+		do {

+			// Clear these in case more than one Semi

+			props.clear(); // on loop, do not want mixed properties

+			name=null;

+			

+			cis = cie+1; // find comma start

+			while(cis<bytes.length && Character.isSpaceChar(bytes[cis]))++cis;

+			cie = cntnt.indexOf(',',cis); // find comma end

+			cend = cie<0?bytes.length:cie; // If no comma, set comma end to full length, else cie

+			while(cend>cis && Character.isSpaceChar(bytes[cend-1]))--cend;

+			// Start SEMIS

+			sie=cis-1; 

+			do {

+				sis = sie+1;  // semi start is one after previous end

+				while(sis<bytes.length && Character.isSpaceChar(bytes[sis]))++sis;	

+				sie = cntnt.indexOf(';',sis);

+				send = sie>cend || sie<0?cend:sie;  // if the Semicolon is after the comma, or non-existent, use comma end, else keep

+				while(send>sis && Character.isSpaceChar(bytes[send-1]))--send;

+				if(name==null) { // first entry in Comma set is the name, not a property

+					name = new String(bytes,sis,send-sis);

+				} else { // We've looped past the first Semi, now process as properties

+					// If there are additional elements (more entities within Semi Colons)

+					// apply Properties

+					int eq = cntnt.indexOf('=',sis);

+					if(eq>sis && eq<send) {

+						props.add(new String(bytes,sis,eq-sis));

+						props.add(new String(bytes,eq+1,send-(eq+1)));

+					}

+				}

+				// End Property

+			} while(sie<=cend && sie>=cis); // End SEMI processing

+			// Now evaluate Comma set and return if true

+			if(eval(code,name,props))return true; // else loop again to check next comma

+		} while(cie>=0); // loop to next comma

+		return false; // didn't get even one match

+	}

+	

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CachingFileAccess.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CachingFileAccess.java
new file mode 100644
index 0000000..019257a
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CachingFileAccess.java
@@ -0,0 +1,476 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.FileNotFoundException;

+import java.io.FileOutputStream;

+import java.io.FileReader;

+import java.io.IOException;

+import java.io.OutputStream;

+import java.io.Writer;

+import java.nio.ByteBuffer;

+import java.nio.channels.FileChannel;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.Map;

+import java.util.Map.Entry;

+import java.util.NavigableMap;

+import java.util.Set;

+import java.util.Timer;

+import java.util.TimerTask;

+import java.util.TreeMap;

+import java.util.concurrent.ConcurrentSkipListMap;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.EnvJAXB;

+import org.onap.aaf.inno.env.LogTarget;

+import org.onap.aaf.inno.env.Store;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+/*

+ * CachingFileAccess

+ * 

+ *  

+ */

+public class CachingFileAccess<TRANS extends Trans> extends HttpCode<TRANS, Void> {

+	public static void setEnv(Store store, String[] args) {

+		for(int i=0;i<args.length-1;i+=2) { // cover two parms required for each 

+			if(CFA_WEB_DIR.equals(args[i])) {

+				store.put(store.staticSlot(CFA_WEB_DIR), args[i+1]); 

+			} else if(CFA_CACHE_CHECK_INTERVAL.equals(args[i])) {

+				store.put(store.staticSlot(CFA_CACHE_CHECK_INTERVAL), Long.parseLong(args[i+1]));

+			} else if(CFA_MAX_SIZE.equals(args[i])) {

+				store.put(store.staticSlot(CFA_MAX_SIZE), Integer.parseInt(args[i+1]));

+			}

+		}

+	}

+	

+	private static String MAX_AGE = "max-age=3600"; // 1 hour Caching

+	private final Map<String,String> typeMap;

+	private final NavigableMap<String,Content> content;

+	private final Set<String> attachOnly;

+	private final static String WEB_DIR_DEFAULT = "theme";

+	public final static String CFA_WEB_DIR = "CFA_WebPath";

+	// when to re-validate from file

+	// Re validating means comparing the Timestamp on the disk, and seeing it has changed.  Cache is not marked

+	// dirty unless file has changed, but it still makes File IO, which for some kinds of cached data, i.e. 

+	// deployed GUI elements is unnecessary, and wastes time.

+	// This parameter exists to cover the cases where data can be more volatile, so the user can choose how often the

+	// File IO will be accessed, based on probability of change.  "0", of course, means, check every time.

+	private final static String CFA_CACHE_CHECK_INTERVAL = "CFA_CheckIntervalMS";

+	private final static String CFA_MAX_SIZE = "CFA_MaxSize"; // Cache size limit

+	private final static String CFA_CLEAR_COMMAND = "CFA_ClearCommand";

+

+	// Note: can be null without a problem, but included

+	// to tie in with existing Logging.

+	public LogTarget logT = null;

+	public long checkInterval; // = 600000L; // only check if not hit in 10 mins by default

+	public int maxItemSize; // = 512000; // max file 500k

+	private Timer timer;

+	private String web_path;

+	// A command key is set in the Properties, preferably changed on deployment.

+	// it is compared at the beginning of the path, and if so, it is assumed to issue certain commands

+	// It's purpose is to protect, to some degree the command, even though it is HTTP, allowing 

+	// local batch files to, for instance, clear caches on resetting of files.

+	private String clear_command;

+	

+	public CachingFileAccess(EnvJAXB env, String ... args) {

+		super(null,"Caching File Access");

+		setEnv(env,args);

+		content = new ConcurrentSkipListMap<String,Content>(); // multi-thread changes possible

+

+		attachOnly = new HashSet<String>();     // short, unchanged

+

+		typeMap = new TreeMap<String,String>(); // Structure unchanged after Construction

+		typeMap.put("ico","image/icon");

+		typeMap.put("html","text/html");

+		typeMap.put("css","text/css");

+		typeMap.put("js","text/javascript");

+		typeMap.put("txt","text/plain");

+		typeMap.put("xml","text/xml");

+		typeMap.put("xsd","text/xml");

+		attachOnly.add("xsd");

+		typeMap.put("crl", "application/x-pkcs7-crl");

+		typeMap.put("appcache","text/cache-manifest");

+

+		typeMap.put("json","text/json");

+		typeMap.put("ogg", "audio/ogg");

+		typeMap.put("jpg","image/jpeg");

+		typeMap.put("gif","image/gif");

+		typeMap.put("png","image/png");

+		typeMap.put("svg","image/svg+xml");

+		typeMap.put("jar","application/x-java-applet");

+		typeMap.put("jnlp", "application/x-java-jnlp-file");

+		typeMap.put("class", "application/java");

+		

+		timer = new Timer("Caching Cleanup",true);

+		timer.schedule(new Cleanup(content,500),60000,60000);

+		

+		// Property params

+		web_path = env.getProperty(CFA_WEB_DIR,WEB_DIR_DEFAULT);

+		Object obj;

+		obj = env.get(env.staticSlot(CFA_CACHE_CHECK_INTERVAL),600000L);  // Default is 10 mins

+		if(obj instanceof Long) {checkInterval=(Long)obj;

+		} else {checkInterval=Long.parseLong((String)obj);}

+		

+		obj = env.get(env.staticSlot(CFA_MAX_SIZE), 512000);    // Default is max file 500k

+		if(obj instanceof Integer) {maxItemSize=(Integer)obj;

+		} else {maxItemSize =Integer.parseInt((String)obj);}

+	 	 	

+	 	clear_command = env.getProperty(CFA_CLEAR_COMMAND,null);

+	}

+

+	

+

+	@Override

+	public void handle(TRANS trans, HttpServletRequest req, HttpServletResponse resp) throws IOException {

+		String key = pathParam(req, ":key");

+		if(key.equals(clear_command)) {

+			String cmd = pathParam(req,":cmd");

+			resp.setHeader("Content-type",typeMap.get("txt"));

+			if("clear".equals(cmd)) {

+				content.clear();

+				resp.setStatus(HttpStatus.OK_200);

+			} else {

+				resp.setStatus(HttpStatus.BAD_REQUEST_400);

+			}

+			return;

+		}

+		Content c = load(logT , web_path,key, null, checkInterval);

+		if(c.attachmentOnly) {

+			resp.setHeader("Content-disposition", "attachment");

+		}

+		c.write(resp.getOutputStream());

+		c.setHeader(resp);

+		trans.checkpoint(req.getPathInfo());

+	}

+

+

+	public String webPath() {

+		return web_path;

+	}

+	

+	/**

+	 * Reset the Cleanup size and interval

+	 * 

+	 * The size and interval when started are 500 items (memory size unknown) checked every minute in a background thread.

+	 * 

+	 * @param size

+	 * @param interval

+	 */

+	public void cleanupParams(int size, long interval) {

+		timer.cancel();

+		timer.schedule(new Cleanup(content,size), interval, interval);

+	}

+	

+

+	

+	/**

+	 * Load a file, first checking cache

+	 * 

+	 * 

+	 * @param logTarget - logTarget can be null (won't log)

+	 * @param dataRoot - data root storage directory

+	 * @param key - relative File Path

+	 * @param mediaType - what kind of file is it.  If null, will check via file extension

+	 * @param timeCheck - "-1" will take system default - Otherwise, will compare "now" + timeCheck(Millis) before looking at File mod

+	 * @return

+	 * @throws IOException

+	 */

+	public Content load(LogTarget logTarget, String dataRoot, String key, String mediaType, long _timeCheck) throws IOException {

+	    long timeCheck = _timeCheck;

+		if(timeCheck<0) {

+			timeCheck=checkInterval; // if time < 0, then use default

+		}

+		String fileName = dataRoot + '/' + key;

+		Content c = content.get(key);

+		long systime = System.currentTimeMillis(); 

+		File f=null;

+		if(c!=null) {

+			// Don't check every hit... only after certain time value

+			if(c.date < systime + timeCheck) {

+				f = new File(fileName);

+				if(f.lastModified()>c.date) {

+					c=null;

+				}

+			}

+		}

+		if(c==null) {	

+			if(logTarget!=null) {

+				logTarget.log("File Read: ",key);

+			}

+			

+			if(f==null){

+				f = new File(fileName);

+			}

+

+			boolean cacheMe;

+			if(f.exists()) {

+				if(f.length() > maxItemSize) {

+					c = new DirectFileContent(f);

+					cacheMe = false;

+				} else {

+					c = new CachedContent(f);

+					cacheMe = checkInterval>0;

+				}

+				

+				if(mediaType==null) { // determine from file Ending

+					int idx = key.lastIndexOf('.');

+					String subkey = key.substring(++idx);

+					if((c.contentType = idx<0?null:typeMap.get(subkey))==null) {

+						// if nothing else, just set to default type...

+						c.contentType = "application/octet-stream";

+					}

+					c.attachmentOnly = attachOnly.contains(subkey);

+				} else {

+					c.contentType=mediaType;

+					c.attachmentOnly = false;

+				}

+				

+				c.date = f.lastModified();

+				

+				if(cacheMe) {

+					content.put(key, c);

+				}

+			} else {

+				c=NULL;

+			}

+		} else {

+			if(logTarget!=null)logTarget.log("Cache Read: ",key);

+		}

+

+		// refresh hit time

+		c.access = systime;

+		return c;

+	}

+	

+	public Content loadOrDefault(Trans trans, String targetDir, String targetFileName, String sourcePath, String mediaType) throws IOException {

+		try {

+			return load(trans.info(),targetDir,targetFileName,mediaType,0);

+		} catch(FileNotFoundException e) {

+			String targetPath = targetDir + '/' + targetFileName;

+			TimeTaken tt = trans.start("File doesn't exist; copy " + sourcePath + " to " + targetPath, Env.SUB);

+			try {

+				FileInputStream sourceFIS = new FileInputStream(sourcePath);

+				FileChannel sourceFC = sourceFIS.getChannel();

+				File targetFile = new File(targetPath);

+				targetFile.getParentFile().mkdirs(); // ensure directory exists

+				FileOutputStream targetFOS = new FileOutputStream(targetFile);

+				try {

+					ByteBuffer bb = ByteBuffer.allocate((int)sourceFC.size());

+					sourceFC.read(bb);

+					bb.flip();  // ready for reading

+					targetFOS.getChannel().write(bb);

+				} finally {

+					sourceFIS.close();

+					targetFOS.close();

+				}

+			} finally {

+				tt.done();

+			}

+			return load(trans.info(),targetDir,targetFileName,mediaType,0);

+		}

+	}

+

+	public void invalidate(String key) {

+		content.remove(key);

+	}

+	

+	private static final Content NULL=new Content() {

+		

+		@Override

+		public void setHeader(HttpServletResponse resp) {

+			resp.setStatus(HttpStatus.NOT_FOUND_404);

+			resp.setHeader("Content-type","text/plain");

+		}

+

+		@Override

+		public void write(Writer writer) throws IOException {

+		}

+

+		@Override

+		public void write(OutputStream os) throws IOException {

+		}

+		

+	};

+

+	private static abstract class Content {

+		private long date;   // date of the actual artifact (i.e. File modified date)

+		private long access; // last accessed

+		

+		protected String  contentType;

+		protected boolean attachmentOnly;

+		

+		public void setHeader(HttpServletResponse resp) {

+			resp.setStatus(HttpStatus.OK_200);

+			resp.setHeader("Content-type",contentType);

+			resp.setHeader("Cache-Control", MAX_AGE);

+		}

+		

+		public abstract void write(Writer writer) throws IOException;

+		public abstract void write(OutputStream os) throws IOException;

+

+	}

+

+	private static class DirectFileContent extends Content {

+		private File file; 

+		public DirectFileContent(File f) {

+			file = f;

+		}

+		

+		public String toString() {

+			return file.getName();

+		}

+		

+		public void write(Writer writer) throws IOException {

+			FileReader fr = new FileReader(file);

+			char[] buff = new char[1024];

+			try {

+				int read;

+				while((read = fr.read(buff,0,1024))>=0) {

+					writer.write(buff,0,read);

+				}

+			} finally {

+				fr.close();

+			}

+		}

+

+		public void write(OutputStream os) throws IOException {

+			FileInputStream fis = new FileInputStream(file);

+			byte[] buff = new byte[1024];

+			try {

+				int read;

+				while((read = fis.read(buff,0,1024))>=0) {

+					os.write(buff,0,read);

+				}

+			} finally {

+				fis.close();

+			}

+		}

+

+	}

+	private static class CachedContent extends Content {

+		private byte[] data;

+		private int end;

+		private char[] cdata; 

+		

+		public CachedContent(File f) throws IOException {

+			// Read and Cache

+			ByteBuffer bb = ByteBuffer.allocate((int)f.length());

+			FileInputStream fis = new FileInputStream(f);

+			try {

+				fis.getChannel().read(bb);

+			} finally {

+				fis.close();

+			}

+

+			data = bb.array();

+			end = bb.position();

+			cdata=null;

+		}

+		

+		public String toString() {

+			return data.toString();

+		}

+		

+		public void write(Writer writer) throws IOException {

+			synchronized(this) {

+				// do the String Transformation once, and only if actually used

+				if(cdata==null) {

+					cdata = new char[end];

+					new String(data).getChars(0, end, cdata, 0);

+				}

+			}

+			writer.write(cdata,0,end);

+		}

+		public void write(OutputStream os) throws IOException {

+			os.write(data,0,end);

+		}

+

+	}

+

+	public void setEnv(LogTarget env) {

+		logT = env;

+	}

+

+	/**

+	 * Cleanup thread to remove older items if max Cache is reached.

+	 *

+	 */

+	private static class Cleanup extends TimerTask {

+		private int maxSize;

+		private NavigableMap<String, Content> content;

+		

+		public Cleanup(NavigableMap<String, Content> content, int size) {

+			maxSize = size;

+			this.content = content;

+		}

+		

+		private class Comp implements Comparable<Comp> {

+			public Map.Entry<String, Content> entry;

+			

+			public Comp(Map.Entry<String, Content> en) {

+				entry = en;

+			}

+			

+			@Override

+			public int compareTo(Comp o) {

+				return (int)(entry.getValue().access-o.entry.getValue().access);

+			}

+			

+		}

+		@SuppressWarnings("unchecked")

+		@Override

+		public void run() {

+			int size = content.size();

+			if(size>maxSize) {

+				ArrayList<Comp> scont = new ArrayList<Comp>(size);

+				Object[] entries = content.entrySet().toArray();

+				for(int i=0;i<size;++i) {

+					scont.add(i, new Comp((Map.Entry<String,Content>)entries[i]));

+				}

+				Collections.sort(scont);

+				int end = size - ((maxSize/4)*3); // reduce to 3/4 of max size

+				System.out.println("------ Cleanup Cycle ------ " + new Date().toString() + " -------");

+				for(int i=0;i<end;++i) {

+					Entry<String, Content> entry = scont.get(i).entry;

+					content.remove(entry.getKey());

+					System.out.println("removed Cache Item " + entry.getKey() + "/" + new Date(entry.getValue().access).toString());

+				}

+				for(int i=end;i<size;++i) {

+					Entry<String, Content> entry = scont.get(i).entry;

+					System.out.println("remaining Cache Item " + entry.getKey() + "/" + new Date(entry.getValue().access).toString());

+				}

+			}

+		}

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CodeSetter.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CodeSetter.java
new file mode 100644
index 0000000..b11c18e
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/CodeSetter.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.inno.env.Trans;

+

+// Package on purpose.  only want between RServlet and Routes

+class CodeSetter<TRANS extends Trans> {

+	private HttpCode<TRANS,?> code;

+	private TRANS trans;

+	private HttpServletRequest req;

+	private HttpServletResponse resp;

+	public CodeSetter(TRANS trans, HttpServletRequest req, HttpServletResponse resp) {

+		this.trans = trans;

+		this.req = req;

+		this.resp = resp;

+				

+	}

+	public boolean matches(Route<TRANS> route) throws IOException, ServletException {

+		// Find best Code in Route based on "Accepts (Get) or Content-Type" (if exists)

+		return (code = route.getCode(trans, req, resp))!=null;

+	}

+	

+	public HttpCode<TRANS,?> code() {

+		return code;

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Content.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Content.java
new file mode 100644
index 0000000..031e8bb
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Content.java
@@ -0,0 +1,115 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.util.List;

+

+import org.onap.aaf.inno.env.Trans;

+

+

+

+/**

+ * A Class to hold Service "ContentTypes", and to match incoming "Accept" types from HTTP.

+ * 

+ * This is a multi-use class built to use the same Parser for ContentTypes and Accept.

+ * 

+ * Thus, you would create and use "Content.Type" within your service, and use it to match

+ * Accept Strings.  What is returned is an Integer (for faster processing), which can be

+ * used in a switch statement to act on match different Actions.  The server should

+ * know which behaviors match.

+ * 

+ * "bestMatch" returns an integer for the best match, or -1 if no matches.

+ *

+ *

+ */

+public abstract class Content<TRANS extends Trans> {

+	public static final String Q = "q";

+	protected abstract Pair<String,Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> types(HttpCode<TRANS,?> code, String str);

+	protected abstract boolean props(Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>> type, String tag, String value);

+

+	/**

+	 * Parse a Content-Type/Accept.  As found, call "types" and "props", which do different

+	 * things depending on if it's a Content-Type or Accepts. 

+	 * 

+	 * For Content-Type, it builds a tree suitable for Comparison

+	 * For Accepts, it compares against the tree, and builds an acceptable type list

+	 * 

+	 * Since this parse code is used for every incoming HTTP transaction, I have removed the implementation

+	 * that uses String.split, and replaced with integers evaluating the Byte array.  This results

+	 * in only the necessary strings created, resulting in 1/3 better speed, and less 

+	 * Garbage collection.

+	 * 

+	 * @param trans

+	 * @param code

+	 * @param cntnt

+	 * @return

+	 */

+	protected boolean parse(HttpCode<TRANS,?> code, String cntnt) {

+		byte bytes[] = cntnt.getBytes();

+		boolean contType=false,contProp=true;

+		int cis,cie=-1,cend;

+		int sis,sie,send;

+		do {

+			cis = cie+1;

+			cie = cntnt.indexOf(',',cis);

+			cend = cie<0?bytes.length:cie;

+			// Start SEMIS

+			sie=cis-1;

+			Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> me = null;

+			do {

+				sis = sie+1;

+				sie = cntnt.indexOf(';',sis);

+				send = sie>cend || sie<0?cend:sie;

+				if(me==null) {

+					String semi = new String(bytes,sis,send-sis);

+					// trans.checkpoint(semi);

+					// Look at first entity within comma group

+					// Is this an acceptable Type?

+					me=types(code, semi);

+					if(me==null) {

+						sie=-1; // skip the rest of the processing... not a type

+					} else {

+						contType=true;

+					}

+				} else { // We've looped past the first Semi, now process as properties

+					// If there are additional elements (more entities within Semi Colons)

+					// apply Propertys

+					int eq = cntnt.indexOf('=',sis);

+					if(eq>sis && eq<send) {

+						String tag = new String(bytes,sis,eq-sis);

+						String value = new String(bytes,eq+1,send-(eq+1));

+						// trans.checkpoint("    Prop " + tag + "=" + value);

+						boolean bool =  props(me,tag,value);

+						if(!bool) {

+							contProp=false;

+						}

+					}

+				}

+				// End Property

+			} while(sie<=cend && sie>=cis);

+			// End SEMIS

+		} while(cie>=0);

+		return contType && contProp; // for use in finds, True if a type found AND all props matched

+	}

+	

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpCode.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpCode.java
new file mode 100644
index 0000000..49a4ba1
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpCode.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * HTTP Code element, which responds to the essential "handle Method".

+ * 

+ * Use Native HttpServletRe[quest|sponse] calls for questions like QueryParameters (getParameter, etc)

+ * 

+ * Use local "pathParam" method to obtain in an optimized manner the path parameter, which must be interpreted by originating string

+ * 

+ * i.e. my/path/:id/:other/*

+ * 

+ *

+ * @param <TRANS>

+ * @param <T>

+ */

+public abstract class HttpCode<TRANS extends Trans, CONTEXT> {

+	protected CONTEXT context;

+	private String desc;

+	protected String [] roles;

+	private boolean all;

+	

+	// Package by design... Set by Route when linked

+	Match match;

+	

+	public HttpCode(CONTEXT context, String description, String ... roles) {

+		this.context = context;

+		desc = description;

+		

+		// Evaluate for "*" once...

+		all = false;

+		for(String srole : roles) {

+			if("*".equals(srole)) {

+				all = true;

+				break;

+			}

+		}

+		this.roles = all?null:roles;

+	}

+	

+	public abstract void handle(TRANS trans, HttpServletRequest req, HttpServletResponse resp) throws Exception;

+	

+	public String desc() {

+		return desc;

+	}

+	

+	/**

+	 * Get the variable element out of the Path Parameter, as set by initial Code

+	 * 

+	 * @param req

+	 * @param key

+	 * @return

+	 */

+	public String pathParam(HttpServletRequest req, String key) {

+		return match.param(req.getPathInfo(), key);

+	}

+

+	// Note: get Query Params from Request

+	

+	/**

+	 * Check for Authorization when set.

+	 * 

+	 * If no Roles set, then accepts all users

+	 * 

+	 * @param req

+	 * @return

+	 */

+	public boolean isAuthorized(HttpServletRequest req) {

+		if(all)return true;

+		if(roles!=null) {

+			for(String srole : roles) {

+				if(req.isUserInRole(srole)) return true;

+			}

+		}

+		return false;

+	}

+	

+	public boolean no_cache() {

+		return false;

+	}

+	

+	public String toString() {

+		return desc;

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpMethods.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpMethods.java
new file mode 100644
index 0000000..7846185
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/HttpMethods.java
@@ -0,0 +1,30 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+public enum HttpMethods {

+	POST,

+	GET,

+	PUT,

+	DELETE

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Match.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Match.java
new file mode 100644
index 0000000..8211024
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Match.java
@@ -0,0 +1,211 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Set;

+

+/**

+ * This path matching algorithm avoids using split strings during the critical transactional run-time.  By pre-analyzing the

+ * content at "set Param" time, and storing data in an array-index model which presumably is done once and at the beginning, 

+ * we can match in much less time when it actually counts.

+ * 

+ *

+ */

+public class Match {

+	private Map<String, Integer> params;

+	private byte[] 	values[];

+	private Integer vars[];

+	private boolean wildcard;

+

+	

+	/*

+	 * These two methods are pairs of searching performance for variables Spark Style.

+	 * setParams evaluates the target path, and sets a HashMap that will return an Integer.

+	 * the Keys are both :key and key so that there will be no string operations during

+	 * a transaction

+	 * 

+	 * For the Integer, if the High Order is 0, then it is just one value.  If High Order >0, then it is 

+	 * a multi-field option, i.e. ending with a wild-card.

+	 */

+	public Match(String path) {

+		// IF DEBUG: System.out.print("\n[" + path + "]");

+		params = new HashMap<String,Integer>();

+		if(path!=null) {

+			String[] pa = path.split("/");

+			values = new byte[pa.length][];

+			vars = new Integer[pa.length];

+			

+			int val = 0;

+			String key;

+			for(int i=0;i<pa.length && !wildcard;++i) {

+				if(pa[i].startsWith(":")) {

+					if(pa[i].endsWith("*")) {

+						val = i | pa.length<<16; // load end value in high order bits

+						key = pa[i].substring(0, pa[i].length()-1);// remove *

+						wildcard = true;

+					} else {

+						val = i;

+						key = pa[i];

+					}

+					params.put(key,val); //put in :key 

+					params.put(key.substring(1,key.length()), val); // put in just key, better than adding a missing one, like Spark

+					// values[i]=null; // null stands for Variable

+					vars[i]=val;

+				} else {

+					values[i]=pa[i].getBytes();

+					if(pa[i].endsWith("*")) {

+						wildcard = true;

+						if(pa[i].length()>1) {

+							/* remove * from value */

+							int newlength = values[i].length-1;

+							byte[] real = new byte[newlength];

+							System.arraycopy(values[i],0,real,0,newlength);

+							values[i]=real;

+						} else {

+							vars[i]=0; // this is actually a variable, if it only contains a "*"

+						}

+					}

+					// vars[i]=null;

+				}

+			}

+		}

+	}

+

+	/*

+	 * This is the second of the param evaluation functions.  First, we look up to see if there is

+	 * any reference by key in the params Map created by the above.

+	 * 

+	 * The resulting Integer, if not null, is split high/low order into start and end.

+	 * We evaluate the string for '/', rather than splitting into  String[] to avoid the time/mem needed

+	 * We traverse to the proper field number for slash, evaluate the end (whether wild card or no), 

+	 * and return the substring.  

+	 * 

+	 * The result is something less than .003 milliseconds per evaluation

+	 * 

+	 */

+	public String param(String path,String key) {

+		Integer val = params.get(key); // :key or key

+		if(val!=null) {

+			int start = val & 0xFFFF;

+			int end = (val >> 16) & 0xFFFF;

+			int idx = -1;

+			int i;

+			for(i=0;i<start;++i) {

+				idx = path.indexOf('/',idx+1);

+				if(idx<0)break;

+			}

+			if(i==start) { 

+				++idx;

+				if(end==0) {

+					end = path.indexOf('/',idx);

+					if(end<0)end=path.length();

+				} else {

+					end=path.length();

+				}

+				return path.substring(idx,end);

+			} else if(i==start-1) { // if last spot was left blank, i.e. :key*

+				return "";

+			}

+		}

+		return null;

+	}

+	

+	public boolean match(String path) {

+		if(path==null|| path.length()==0 || "/".equals(path) ) {

+			if(values==null)return true;

+			switch(values.length) {

+				case 0: return true;

+				case 1: return values[0].length==0;

+				default: return false;

+			}

+		}			

+		boolean rv = true;

+		byte[] pabytes = path.getBytes();

+		int field=0;

+		int fieldIdx = 0;

+

+		int lastField = values.length;

+		int lastByte = pabytes.length;

+		boolean fieldMatched = false; // = lastByte>0?(pabytes[0]=='/'):false;

+		// IF DEBUG: System.out.println("\n -- " + path + " --");

+		for(int i=0;rv && i<lastByte;++i) {

+			if(field>=lastField) { // checking here allows there to be a non-functional ending /

+				rv = false;

+				break;

+			}

+			if(values[field]==null) { // it's a variable, just look for /s

+				if(wildcard && field==lastField-1) return true;// we've made it this far.  We accept all remaining characters

+				Integer val = vars[field];

+				int start = val & 0xFFFF;

+				int end = (val >> 16) & 0xFFFF;

+				if(end==0)end=start+1;

+				int k = i;

+				for(int j=start; j<end && k<lastByte; ++k) {

+					// IF DEBUG: System.out.print((char)pabytes[k]);

+					if(pabytes[k]=='/') {

+						++field;

+						++j;

+					}

+				}

+				

+				if(k==lastByte && pabytes[k-1]!='/')++field;

+				if(k>i)i=k-1; // if we've incremented, have to accommodate the outer for loop incrementing as well

+				fieldMatched = false; // reset

+				fieldIdx = 0;

+			} else {

+				// IF DEBUG: System.out.print((char)pabytes[i]);

+				if(pabytes[i]=='/') { // end of field, eval if Field is matched

+					// if double slash, check if supposed to be empty

+					if(fieldIdx==0 && values[field].length==0) {

+						fieldMatched = true;

+					}

+					rv = fieldMatched && ++field<lastField;

+					// reset

+					fieldMatched = false; 

+					fieldIdx = 0;

+				} else if(values[field].length==0) {

+					// double slash in path, but content in field.  We check specially here to avoid 

+					// Array out of bounds issues.

+					rv = false;

+				} else {

+					if(fieldMatched) {

+						rv =false; // field is already matched, now there's too many bytes

+					} else {

+						rv = pabytes[i]==values[field][fieldIdx++]; // compare expected (pabytes[i]) with value for particular field

+						fieldMatched=values[field].length==fieldIdx; // are all the bytes match in the field?

+						if(fieldMatched && (i==lastByte-1 || (wildcard && field==lastField-1)))

+							return true; // last field info

+					}

+				}

+			}

+		}

+		if(field!=lastField || pabytes.length!=lastByte) rv = false; // have we matched all the fields and all the bytes?

+		return rv;

+	}

+	

+	public Set<String> getParamNames() {

+		return params.keySet();

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Pair.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Pair.java
new file mode 100644
index 0000000..e6ed58b
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Pair.java
@@ -0,0 +1,43 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+/**

+ * A pair of generic Objects.  

+ *

+ * @param <X>

+ * @param <Y>

+ */

+public class Pair<X,Y> {

+	public X x;

+	public Y y;

+	

+	public Pair(X x, Y y) {

+		this.x = x;

+		this.y = y;

+	}

+	

+	public String toString() {

+		return "X: " + x.toString() + "-->" + y.toString();

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RServlet.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RServlet.java
new file mode 100644
index 0000000..cf22539
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RServlet.java
@@ -0,0 +1,155 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.util.List;

+

+import javax.servlet.Servlet;

+import javax.servlet.ServletConfig;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+public abstract class RServlet<TRANS extends Trans> implements Servlet {

+	private Routes<TRANS> routes = new Routes<TRANS>();

+

+	private ServletConfig config;

+

+	@Override

+	public void init(ServletConfig config) throws ServletException {

+		this.config = config;

+	}

+

+	@Override

+	public ServletConfig getServletConfig() {

+		return config;

+	}

+

+	public void route(Env env, HttpMethods meth, String path, HttpCode<TRANS, ?> code, String ... moreTypes) {

+		Route<TRANS> r = routes.findOrCreate(meth,path);

+		r.add(code,moreTypes);

+		env.init().log(r.report(code),code);

+	}

+	

+	@Override

+	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {

+		HttpServletRequest request = (HttpServletRequest)req;

+		HttpServletResponse response = (HttpServletResponse)res;

+		

+		@SuppressWarnings("unchecked")

+		TRANS trans = (TRANS)req.getAttribute(TransFilter.TRANS_TAG);

+		if(trans==null) {

+			response.setStatus(404); // Not Found, because it didn't go through TransFilter

+			return;

+		}

+		

+		Route<TRANS> route;

+		HttpCode<TRANS,?> code=null;

+		String ct = req.getContentType();

+		TimeTaken tt = trans.start("Resolve to Code", Env.SUB);

+		try {

+			// routes have multiple code sets.  This object picks the best code set

+			// based on Accept or Content-Type

+			CodeSetter<TRANS> codesetter = new CodeSetter<TRANS>(trans,request,response);

+			// Find declared route

+			route = routes.derive(request, codesetter);

+			if(route==null) {

+				String method = request.getMethod();

+				trans.checkpoint("No Route matches "+ method + ' ' + request.getPathInfo());

+				response.setStatus(404); // Not Found

+			} else {

+				// Find best Code in Route based on "Accepts (Get) or Content-Type" (if exists)

+				code = codesetter.code();// route.getCode(trans, request, response);

+			}

+		} finally {

+			tt.done();

+		}

+		

+		if(route!=null && code!=null) {

+			StringBuilder sb = new StringBuilder(72);

+			sb.append(route.auditText);

+			sb.append(',');

+			sb.append(code.desc());

+			if(ct!=null) {

+				sb.append(", ContentType: ");

+				sb.append(ct);

+			}

+			tt = trans.start(sb.toString(),Env.SUB);

+			try {

+				/*obj = */

+				code.handle(trans, request, response);

+				response.flushBuffer();

+			} catch (ServletException e) {

+				trans.error().log(e);

+				throw e;

+			} catch (Exception e) {

+				trans.error().log(e,request.getMethod(),request.getPathInfo());

+				throw new ServletException(e);

+			} finally {

+				tt.done();

+			}

+		}

+	}

+	

+	@Override

+	public String getServletInfo() {

+		return "RServlet for Jetty";

+	}

+

+	@Override

+	public void destroy() {

+	}

+

+	public String applicationJSON(Class<?> cls, String version) {

+		StringBuilder sb = new StringBuilder();

+		sb.append("application/");

+		sb.append(cls.getSimpleName());

+		sb.append("+json");

+		sb.append(";charset=utf-8");

+		sb.append(";version=");

+		sb.append(version);

+		return sb.toString();

+	}

+

+	public String applicationXML(Class<?> cls, String version) {

+		StringBuilder sb = new StringBuilder();

+		sb.append("application/");

+		sb.append(cls.getSimpleName());

+		sb.append("+xml");

+		sb.append(";charset=utf-8");

+		sb.append(";version=");

+		sb.append(version);

+		return sb.toString();

+	}

+

+	public List<RouteReport> routeReport() {

+		return routes.routeReport();

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Route.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Route.java
new file mode 100644
index 0000000..9d9253d
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Route.java
@@ -0,0 +1,142 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.util.List;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+public class Route<TRANS extends Trans> {

+	public final String auditText;

+	public final HttpMethods meth;

+	public final String path;

+	

+	private Match match;

+	// package on purpose

+	private final TypedCode<TRANS> content;

+	private final boolean isGet;

+	

+	public Route(HttpMethods meth, String path) {

+		this.path = path;

+		auditText = meth.name() + ' ' + path;

+		this.meth = meth; // Note: Using Spark def for now.

+		isGet = meth.compareTo(HttpMethods.GET) == 0;

+		match = new Match(path);

+		content = new TypedCode<TRANS>();

+	}

+	

+	public void add(HttpCode<TRANS,?> code, String ... others) {

+		code.match = match;

+		content.add(code, others);

+	}

+	

+//	public void add(HttpCode<TRANS,?> code, Class<?> cls, String version, String ... others) {

+//		code.match = match;

+//		content.add(code, cls, version, others);

+//	}

+//

+	public HttpCode<TRANS,?> getCode(TRANS trans, HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {

+		// Type is associated with Accept for GET (since it is what is being returned

+		// We associate the rest with ContentType.

+		// FYI, thought about this a long time before implementing this way.

+		String compare;

+//		String special[]; // todo, expose Charset (in special) to outside

+		if(isGet) {

+			compare = req.getHeader("Accept"); // Accept is used for read, as we want to agree on what caller is ready to handle

+		} else {

+			compare = req.getContentType(); // Content type used to declare what data is being created, updated or deleted (might be used for key)

+		}

+

+		Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> hl = content.prep(trans, compare);

+		if(hl==null) {

+			resp.setStatus(406); // NOT_ACCEPTABLE

+		} else {

+			if(isGet) { // Set Content Type to expected content

+				if("*".equals(hl.x) || "*/*".equals(hl.x)) {// if wild-card, then choose first kind of type

+					resp.setContentType(content.first());

+				} else {

+					resp.setContentType(hl.x);

+				}

+			}

+			return hl.y.x;

+		}

+		return null;

+	}

+	

+	public Route<TRANS> matches(String method, String path) {

+		return meth.name().equalsIgnoreCase(method) && match.match(path)?this:null;

+	}

+	

+	public TimeTaken start(Trans trans, String auditText, HttpCode<TRANS,?> code, String type) {

+		StringBuilder sb = new StringBuilder(auditText);

+		sb.append(", ");

+		sb.append(code.desc());

+		sb.append(", Content: ");

+		sb.append(type);

+		return trans.start(sb.toString(), Env.SUB);

+	}

+

+	// Package on purpose.. for "find/Create" routes only

+	boolean resolvesTo(HttpMethods hm, String p) {

+		return(path.equals(p) && hm.equals(meth));

+	}

+	

+	public String toString() {

+		return auditText + ' ' + content; 

+	}

+

+	public String report(HttpCode<TRANS, ?> code) {

+		StringBuilder sb = new StringBuilder();

+		sb.append(auditText);

+		sb.append(' ');

+		content.relatedTo(code, sb);

+		return sb.toString();

+	}

+

+	public RouteReport api() {

+		RouteReport tr = new RouteReport();

+		tr.meth = meth;

+		tr.path = path;

+		content.api(tr);

+		return tr;

+	}

+

+

+	/**

+	 * contentRelatedTo (For reporting) list routes that will end up at a specific Code

+	 * @return

+	 */

+	public String contentRelatedTo(HttpCode<TRANS, ?> code) {

+		StringBuilder sb = new StringBuilder(path);

+		sb.append(' ');

+		content.relatedTo(code, sb);

+		return sb.toString();

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RouteReport.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RouteReport.java
new file mode 100644
index 0000000..8e134f1
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/RouteReport.java
@@ -0,0 +1,34 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.util.ArrayList;

+import java.util.List;

+

+public class RouteReport {

+	public HttpMethods meth;

+	public String path;

+	public String desc;

+	public final List<String> contextTypes = new ArrayList<String>();

+

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Routes.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Routes.java
new file mode 100644
index 0000000..60f0039
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Routes.java
@@ -0,0 +1,90 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.inno.env.Trans;

+

+

+public class Routes<TRANS extends Trans> {

+	// Since this must be very, very fast, and only needs one creation, we'll use just an array.

+	private Route<TRANS>[] routes;

+	private int end;

+	

+

+	@SuppressWarnings("unchecked")

+	public Routes() {

+		routes = new Route[10];

+		end = 0;

+	}

+	

+	// This method for setup of Routes only...

+	// Package on purpose

+	synchronized Route<TRANS> findOrCreate(HttpMethods  meth, String path) {

+		Route<TRANS> rv = null;

+		for(int i=0;i<end;++i) {

+			if(routes[i].resolvesTo(meth,path))rv = routes[i];

+		}

+		

+		if(rv==null) {

+			if(end>=routes.length) {

+				@SuppressWarnings("unchecked")

+				Route<TRANS>[] temp = new Route[end+10];

+				System.arraycopy(routes, 0, temp, 0, routes.length);

+				routes = temp;

+			}

+			

+			routes[end++]=rv=new Route<TRANS>(meth,path);

+		}

+		return rv;

+	}

+	

+	public Route<TRANS> derive(HttpServletRequest req, CodeSetter<TRANS> codeSetter)  throws IOException, ServletException {

+		Route<TRANS> rv = null;

+		String path = req.getPathInfo();

+		String meth = req.getMethod();

+		//TODO a TREE would be better

+		for(int i=0;rv==null && i<end; ++i) {

+			rv = routes[i].matches(meth,path);

+			if(rv!=null && !codeSetter.matches(rv)) { // potential match, check if has Code 

+				rv = null; // not quite, keep going

+			}

+		}

+		//TODO a Default?

+		return rv;

+	}

+	

+	public List<RouteReport> routeReport() {

+		ArrayList<RouteReport> ltr = new ArrayList<RouteReport>();

+		for(int i=0;i<end;++i) {

+			ltr.add(routes[i].api());

+		}

+		return ltr;

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransFilter.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransFilter.java
new file mode 100644
index 0000000..f7fa997
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransFilter.java
@@ -0,0 +1,136 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.security.Principal;

+

+import javax.servlet.Filter;

+import javax.servlet.FilterChain;

+import javax.servlet.FilterConfig;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.cadi.Access;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.CadiWrap;

+import org.onap.aaf.cadi.Connector;

+import org.onap.aaf.cadi.Lur;

+import org.onap.aaf.cadi.TrustChecker;

+import org.onap.aaf.cadi.filter.CadiHTTPManip;

+import org.onap.aaf.cadi.taf.TafResp;

+import org.onap.aaf.cadi.taf.TafResp.RESP;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.TransStore;

+

+/**

+ * Create a new Transaction Object for each and every incoming Transaction

+ * 

+ * Attach to Request.  User "FilterHolder" mechanism to retain single instance.

+ * 

+ * TransFilter includes CADIFilter as part of the package, so that it can

+ * set User Data, etc, as necessary.

+ * 

+ *

+ */

+public abstract class TransFilter<TRANS extends TransStore> implements Filter {

+	public static final String TRANS_TAG = "__TRANS__";

+	

+	private CadiHTTPManip cadi;

+	

+	public TransFilter(Access access, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException {

+		cadi = new CadiHTTPManip(access, con, tc, additionalTafLurs);

+	}

+

+	@Override

+	public void init(FilterConfig filterConfig) throws ServletException {

+	}

+	

+	protected Lur getLur() {

+		return cadi.getLur();

+	}

+

+	protected abstract TRANS newTrans();

+	protected abstract TimeTaken start(TRANS trans, ServletRequest request);

+	protected abstract void authenticated(TRANS trans, Principal p);

+	protected abstract void tallyHo(TRANS trans);

+	

+	@Override

+	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

+		TRANS trans = newTrans();

+		

+		TimeTaken overall = start(trans,request);

+		try {

+			request.setAttribute(TRANS_TAG, trans);

+			

+			HttpServletRequest req = (HttpServletRequest)request;

+			HttpServletResponse res = (HttpServletResponse)response;

+			

+			TimeTaken security = trans.start("CADI Security", Env.SUB);

+//			TimeTaken ttvalid;

+			TafResp resp;

+			RESP r;

+			CadiWrap cw = null;

+			try {

+				resp = cadi.validate(req,res);

+				switch(r=resp.isAuthenticated()) {

+					case IS_AUTHENTICATED:

+						cw = new CadiWrap(req,resp,cadi.getLur());

+						authenticated(trans, cw.getUserPrincipal());

+						break;

+					default:

+						break;

+				}

+			} finally {

+				security.done();

+			}

+			

+			if(r==RESP.IS_AUTHENTICATED) {

+				trans.checkpoint(resp.desc());

+				chain.doFilter(cw, response);

+			} else {

+				//TODO this is a good place to check if too many checks recently

+				// Would need Cached Counter objects that are cleaned up on 

+				// use

+				trans.checkpoint(resp.desc(),Env.ALWAYS);

+				if(resp.isFailedAttempt())

+						trans.audit().log(resp.desc());

+			}

+		} catch(Exception e) {

+			trans.error().log(e);

+			trans.checkpoint("Error: " + e.getClass().getSimpleName() + ": " + e.getMessage());

+			throw new ServletException(e);

+		} finally {

+			overall.done();

+			tallyHo(trans);

+		}

+	}

+

+	@Override

+	public void destroy() {

+	};

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransOnlyFilter.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransOnlyFilter.java
new file mode 100644
index 0000000..93599b2
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TransOnlyFilter.java
@@ -0,0 +1,77 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.security.Principal;

+

+import javax.servlet.Filter;

+import javax.servlet.FilterChain;

+import javax.servlet.FilterConfig;

+import javax.servlet.ServletException;

+import javax.servlet.ServletRequest;

+import javax.servlet.ServletResponse;

+

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.TransStore;

+

+/**

+ * Create a new Transaction Object for each and every incoming Transaction

+ * 

+ * Attach to Request.  User "FilterHolder" mechanism to retain single instance.

+ * 

+ * TransFilter includes CADIFilter as part of the package, so that it can

+ * set User Data, etc, as necessary.

+ * 

+ *

+ */

+public abstract class TransOnlyFilter<TRANS extends TransStore> implements Filter {

+	@Override

+	public void init(FilterConfig filterConfig) throws ServletException {

+	}

+	

+

+

+	protected abstract TRANS newTrans();

+	protected abstract TimeTaken start(TRANS trans, ServletRequest request);

+	protected abstract void authenticated(TRANS trans, Principal p);

+	protected abstract void tallyHo(TRANS trans);

+	

+	@Override

+	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

+		TRANS trans = newTrans();

+		

+		TimeTaken overall = start(trans,request);

+		try {

+			request.setAttribute(TransFilter.TRANS_TAG, trans);

+			chain.doFilter(request, response);

+		} finally {

+			overall.done();

+		}

+		tallyHo(trans);

+	}

+

+	@Override

+	public void destroy() {

+	};

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TypedCode.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TypedCode.java
new file mode 100644
index 0000000..e1aaf1d
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/TypedCode.java
@@ -0,0 +1,268 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+

+import javax.servlet.ServletException;

+

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.Trans;

+

+

+/**

+ * TypedCode organizes implementation code based on the Type and Version of code it works with so that it can

+ * be located quickly at runtime based on the "Accept" HTTP Header.

+ *

+ * FYI: For those in the future wondering why I would create a specialized set of "Pair" for the data content:

+ *   1) TypeCode is used in Route, and this code is used for every transaction... it needs to be blazingly fast

+ *   2) The actual number of objects accessed is quite small and built at startup.  Arrays are best

+ *   3) I needed a small, well defined tree where each level is a different Type.  Using a "Pair" Generic definitions, 

+ *      I created type-safety at each level, which you can't get from a TreeSet, etc.

+ *   4) Chaining through the Network is simply object dereferencing, which is as fast as Java can go.

+ *   5) The drawback is that in your code is that all the variables are named "x" and "y", which can be a bit hard to

+ *   	read both in code, and in the debugger.  However, TypeSafety allows your IDE (Eclipse) to help you make the 

+ *      choices.  Also, make sure you have a good "toString()" method on each object so you can see what's happening

+ *      in the IDE Debugger.

+ *   

+ * Empirically, this method of obtaining routes proved to be much faster than the HashSet implementations available in otherwise

+ * competent Open Source.

+ *

+ * @param <TRANS>

+ */

+public class TypedCode<TRANS extends Trans> extends Content<TRANS> {

+		private List<Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String, Object>>>>> types;

+

+		public TypedCode() {

+			types = new ArrayList<Pair<String,Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>>>();

+		}

+		

+		/**

+		 * Construct Typed Code based on ContentType parameters passed in

+		 * 

+		 * @param code

+		 * @param others

+		 * @return

+		 */

+		public TypedCode<TRANS> add(HttpCode<TRANS,?> code, String ... others) {

+			StringBuilder sb = new StringBuilder();

+			boolean first = true;

+			for(String str : others) {

+				if(first) {

+					first = false; 

+				} else {

+					sb.append(',');

+				}

+				sb.append(str);

+			}

+			parse(code, sb.toString());

+			

+			return this;

+		}

+		

+		@Override

+		protected Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> types(HttpCode<TRANS,?> code, String str) {

+			Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String, Object>>>> type = null;

+			ArrayList<Pair<String, Object>> props = new ArrayList<Pair<String,Object>>();

+			// Want Q percentage is to be first in the array everytime.  If not listed, 1.0 is default

+			props.add(new Pair<String,Object>(Q,1f));

+			Pair<HttpCode<TRANS,?>, List<Pair<String,Object>>> cl = new Pair<HttpCode<TRANS,?>, List<Pair<String,Object>>>(code, props);

+//			// breakup "plus" stuff, i.e. application/xaml+xml

+//			int plus = str.indexOf('+');

+//			if(plus<0) {

+				type = new Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>>(str, cl);

+				types.add(type);

+				return type;

+//			} else {

+//				int prev = str.indexOf('/')+1;

+//				String first = str.substring(0,prev);

+//				String nstr;

+//				while(prev!=0) {

+//					nstr = first + (plus>-1?str.substring(prev,plus):str.substring(prev));

+//					type = new Pair<String, Pair<HttpCode<TRANS,?>,List<Pair<String,Object>>>>(nstr, cl);

+//					types.add(type);

+//					prev = plus+1;

+//					plus = str.indexOf('+',prev);

+//				}

+//			return type;

+//			}

+		}

+

+		@Override

+		protected boolean props(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type, String tag, String value) {

+			if(tag.equals(Q)) { // reset the Q value (first in array)

+				boolean rv = true;

+				try {

+					type.y.y.get(0).y=Float.parseFloat(value);

+					return rv;

+				} catch (NumberFormatException e) {

+					rv=false; // Note: this awkward syntax forced by Sonar, which doesn't like doing nothing with Exception

+							  // which is what should happen

+				}

+			}

+			return type.y.y.add(new Pair<String,Object>(tag,"version".equals(tag)?new Version(value):value));

+		}

+		

+		public Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> prep(TRANS trans, String compare) throws IOException, ServletException {

+			Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> c,rv=null;

+			if(types.size()==1 && "".equals((c=types.get(0)).x)) { // if there are no checks for type, skip

+				rv = c;

+			} else {

+				if(compare==null || compare.length()==0) {

+					rv = types.get(0); // first code is used

+				} else {

+					Acceptor<TRANS> acc = new Acceptor<TRANS>(types);

+					boolean accepted;

+					TimeTaken tt = trans.start(compare, Env.SUB);

+					try {

+						accepted = acc.parse(null, compare);

+					} finally {

+						tt.done();

+					}

+					if(accepted) {

+						switch(acc.acceptable.size()) {

+							case 0:	

+//								// TODO best Status Code?

+//								resp.setStatus(HttpStatus.NOT_ACCEPTABLE_406);

+								break;

+							case 1: 

+								rv = acc.acceptable.get(0);

+								break;

+							default: // compare Q values to get Best Match

+								float bestQ = -1.0f;

+								Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> bestT = null;

+								for(Pair<String, Pair<HttpCode<TRANS,?>, List<Pair<String, Object>>>> type : acc.acceptable) {

+									Float f = (Float)type.y.y.get(0).y; // first property is always Q

+									if(f>bestQ) {

+										bestQ=f;

+										bestT = type;

+									}

+								}

+								if(bestT!=null) {

+									// When it is a GET, the matched type is what is returned, so set ContentType

+//									if(isGet)resp.setContentType(bestT.x); // set ContentType of Code<TRANS,?>

+//									rv = bestT.y.x;

+									rv = bestT;

+								}

+						}

+					} else {

+						trans.checkpoint("No Match found for Accept");

+					}

+				}

+			}

+			return rv;

+		}

+		

+		/**

+		 * Print on String Builder content related to specific Code

+		 * 

+		 * This is for Reporting and Debugging purposes, so the content is not cached.

+		 * 

+		 * If code is "null", then all content is matched

+		 * 

+		 * @param code

+		 * @return

+		 */

+		public StringBuilder relatedTo(HttpCode<TRANS, ?> code, StringBuilder sb) {

+			boolean first = true;

+			for(Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> pair : types) {

+				if(code==null || pair.y.x == code) {

+					if(first) {

+						first = false;

+					} else {

+						sb.append(',');

+					}

+					sb.append(pair.x);

+					for(Pair<String,Object> prop : pair.y.y) {

+						// Don't print "Q".  it's there for internal use, but it is only meaningful for "Accepts"

+						if(!prop.x.equals(Q) || !prop.y.equals(1f) ) {

+							sb.append(';');

+							sb.append(prop.x);

+							sb.append('=');

+							sb.append(prop.y);

+						}

+					}

+				}

+			}

+			return sb;

+		}

+		

+		public List<Pair<String, Object>> getContent(HttpCode<TRANS,?> code) {

+			for(Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> pair : types) {

+				if(pair.y.x == code) {

+					return pair.y.y;

+				}

+			}

+			return null;

+		}

+	

+		public String toString() {

+			return relatedTo(null,new StringBuilder()).toString();

+		}

+		

+		public void api(RouteReport tr) {

+			// Need to build up a map, because Prop entries can be in several places.

+			HashMap<HttpCode<?,?>,StringBuilder> psb = new HashMap<HttpCode<?,?>,StringBuilder>();

+			StringBuilder temp;

+			tr.desc = null;

+			

+			// Read through Code/TypeCode trees for all accepted Typecodes

+			for(Pair<String, Pair<HttpCode<TRANS, ?>, List<Pair<String, Object>>>> tc : types) {

+				// If new, then it's new Code set, create prefix content

+				if((temp=psb.get(tc.y.x))==null) {

+					psb.put(tc.y.x,temp=new StringBuilder());

+					if(tr.desc==null) {

+						tr.desc = tc.y.x.desc();

+					}

+				} else {

+					temp.append(',');

+				}

+				temp.append(tc.x);

+

+				// add all properties

+				for(Pair<String, Object> props : tc.y.y) {

+					temp.append(';');

+					temp.append(props.x);

+					temp.append('=');

+					temp.append(props.y);

+				}

+			}

+			// Gather all ContentType possibilities for the same code together

+			

+			for(StringBuilder sb : psb.values()) {

+				tr.contextTypes.add(sb.toString());

+			}

+		}

+

+		public String first() {

+			if(types.size()>0) {

+				return types.get(0).x;

+			}

+			return null;

+		}

+		

+	}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Version.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Version.java
new file mode 100644
index 0000000..ff02cef
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/Version.java
@@ -0,0 +1,93 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+

+/**

+ * Analyze and hold Version information for Code

+ * 

+ *

+ */

+public class Version {

+	private Object[] parts;

+

+	public Version(String v) {

+		String sparts[] = v.split("\\.");

+		parts = new Object[sparts.length];

+		System.arraycopy(sparts, 0, parts, 0, sparts.length);

+		if(parts.length>1) { // has at least a minor

+		  try {

+			  parts[1]=Integer.decode(sparts[1]); // minor elements need to be converted to Integer for comparison

+		  } catch (NumberFormatException e) {

+			  // it's ok, leave it as a string

+			  parts[1]=sparts[1]; // This useless piece of code forced by Sonar which calls empty Exceptions "Blockers".

+		  }

+		}

+	}

+

+	public boolean equals(Object obj) {

+		if(obj instanceof Version) {

+			Version ver = (Version)obj;

+			int length = Math.min(parts.length, ver.parts.length);

+			for(int i=0;i<length;++i) { // match on declared parts

+				if(i==1) {

+					if(parts[1] instanceof Integer && ver.parts[1] instanceof Integer) {

+						// Match on Minor version if this Version is less than Version to be checked

+						if(((Integer)parts[1])<((Integer)ver.parts[1])) {

+							return false;

+						}

+						continue; // don't match next line

+					}

+				}

+				if(!parts[i].equals(ver.parts[i])) {

+					return false; // other spots exact match

+				}

+			}

+			return true;

+		}

+		return false;

+	}

+	

+	

+	/* (non-Javadoc)

+	 * @see java.lang.Object#hashCode()

+	 */

+	@Override

+	public int hashCode() {

+		return super.hashCode();

+	}

+

+	public String toString() {

+		StringBuilder sb = new StringBuilder();

+		boolean first = true;

+		for(Object obj : parts) {

+			if(first) {

+				first = false;

+			} else {

+				sb.append('.');

+			}

+			sb.append(obj.toString());

+		}

+		return sb.toString();

+	}

+}

diff --git a/authz-core/src/main/java/org/onap/aaf/cssa/rserv/doc/ApiDoc.java b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/doc/ApiDoc.java
new file mode 100644
index 0000000..b95b383
--- /dev/null
+++ b/authz-core/src/main/java/org/onap/aaf/cssa/rserv/doc/ApiDoc.java
@@ -0,0 +1,42 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv.doc;

+

+import java.lang.annotation.ElementType;

+import java.lang.annotation.Retention;

+import java.lang.annotation.RetentionPolicy;

+import java.lang.annotation.Target;

+

+import org.onap.aaf.cssa.rserv.HttpMethods;

+@Retention(RetentionPolicy.RUNTIME)

+@Target({ElementType.METHOD})

+public @interface ApiDoc {

+	HttpMethods method();

+	String path();

+	int expectedCode();

+	int[] errorCodes();

+	String[] text();

+	/** Format with name|type|[true|false] */

+	String[] params();

+	

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/common/JU_Define.java b/authz-core/src/test/java/org/onap/aaf/authz/common/JU_Define.java
new file mode 100644
index 0000000..48c8499
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/common/JU_Define.java
@@ -0,0 +1,64 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.common;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Matchers;

+import org.mockito.Mock;

+import org.onap.aaf.authz.common.Define;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.Env;

+

+@RunWith(PowerMockRunner.class)

+public class JU_Define {

+	Define define;

+	public static String ROOT_NS="NS.Not.Set";

+	public static String ROOT_COMPANY=ROOT_NS;

+	

+	@Mock 

+	Env envMock;

+	

+	

+	@Before

+	public void setUp(){

+		define = new Define();

+	}

+

+	@Test

+	public void testSet() throws CadiException {

+		PowerMockito.when(envMock.getProperty(Config.AAF_ROOT_NS)).thenReturn("aaf_root_ns");

+		PowerMockito.when(envMock.getProperty(Config.AAF_ROOT_COMPANY)).thenReturn("aaf_root_company");

+		//PowerMockito.when(envMock.init().log()).thenReturn(null);

+		//PowerMockito.doNothing().doThrow(new CadiException()).when(envMock).init().log(Matchers.anyString());

+		define.set(envMock);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzEnv.java b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzEnv.java
new file mode 100644
index 0000000..937b03d
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzEnv.java
@@ -0,0 +1,70 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.cadi.Access.Level;

+

+@RunWith(PowerMockRunner.class)

+public class JU_AuthzEnv {

+	private static final org.onap.aaf.cadi.Access.Level DEBUG = null;

+	AuthzEnv authzEnv;

+	enum Level {DEBUG, INFO, AUDIT, INIT, WARN, ERROR};

+	

+	@Before

+	public void setUp(){

+		authzEnv = new AuthzEnv();

+	}

+

+	@Test

+	public void testTransRate() {

+	Long Result =	authzEnv.transRate();

+	System.out.println("value of result " +Result); //Expected 300000

+	assertNotNull(Result);		

+	}

+	

+	@Test(expected = IOException.class)

+	public void testDecryptException() throws IOException{

+		String encrypted = null;

+		authzEnv.decrypt(encrypted, true);

+	}

+	

+	@Test

+	public void testDecrypt() throws IOException{

+		String encrypted = "encrypted";

+		String Result = authzEnv.decrypt(encrypted, true);

+		System.out.println("value of res " +Result);

+		assertEquals("encrypted",Result);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransFilter.java b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransFilter.java
new file mode 100644
index 0000000..1a15da1
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransFilter.java
@@ -0,0 +1,83 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.env.AuthzTransFilter;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.Connector;

+import org.onap.aaf.cadi.TrustChecker;

+

+@RunWith(PowerMockRunner.class)  

+public class JU_AuthzTransFilter {

+AuthzTransFilter authzTransFilter;

+@Mock

+AuthzEnv authzEnvMock;

+@Mock

+Connector connectorMock;

+@Mock

+TrustChecker trustCheckerMock;

+@Mock

+AuthzTrans authzTransMock;

+Object additionalTafLurs;

+	

+	@Before

+	public void setUp(){

+		try {

+			authzTransFilter = new AuthzTransFilter(authzEnvMock, connectorMock, trustCheckerMock, additionalTafLurs);

+		} catch (CadiException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void test()

+	{

+		//authzTransFilter.newTrans();

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testTallyHo(){

+		PowerMockito.when(authzTransMock.info().isLoggable()).thenReturn(true);

+		//if(trans.info().isLoggable())

+		authzTransFilter.tallyHo(authzTransMock);

+		

+	}

+	

+	

+//	AuthzTrans at = env.newTrans();

+//	at.setLur(getLur());

+//	return at

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransImpl.java b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransImpl.java
new file mode 100644
index 0000000..901f94e
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransImpl.java
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTransImpl;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.OrganizationFactory;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.LogTarget;

+

+@RunWith(PowerMockRunner.class)

+public class JU_AuthzTransImpl {

+

+	AuthzTransImpl authzTransImpl;

+	@Mock

+	AuthzEnv authzEnvMock;

+	

+	private Organization org=null;

+	

+	@Before

+	public void setUp(){

+		authzTransImpl = new AuthzTransImpl(authzEnvMock);

+		

+	}

+	

+	@Test

+	public void testOrg(){

+		Organization result=null;

+		result = authzTransImpl.org();

+		System.out.println("value of Organization " + result);

+		//assertTrue(true);	

+	}

+	

+	@Mock

+	LogTarget logTargetMock;

+	

+	@Test

+	public void testLogAuditTrail(){

+		

+		PowerMockito.when(logTargetMock.isLoggable()).thenReturn(false);

+		authzTransImpl.logAuditTrail(logTargetMock);

+		

+		assertTrue(true);

+	}

+	

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransOnlyFilter.java b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransOnlyFilter.java
new file mode 100644
index 0000000..d55a634
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_AuthzTransOnlyFilter.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTransOnlyFilter;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_AuthzTransOnlyFilter {

+	AuthzTransOnlyFilter authzTransOnlyFilter;

+	@Mock

+	AuthzEnv authzEnvMock;

+	

+	@Before

+	public void setUp(){

+		authzTransOnlyFilter = new AuthzTransOnlyFilter(authzEnvMock);

+	}

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/env/JU_NullTrans.java b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_NullTrans.java
new file mode 100644
index 0000000..5ee7066
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/env/JU_NullTrans.java
@@ -0,0 +1,47 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.env;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.env.NullTrans;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_NullTrans {

+	NullTrans nullTrans;

+	

+	@Before

+	public void setUp(){

+		nullTrans = new NullTrans();

+	}

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/layer/JU_Result.java b/authz-core/src/test/java/org/onap/aaf/authz/layer/JU_Result.java
new file mode 100644
index 0000000..e276e68
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/layer/JU_Result.java
@@ -0,0 +1,54 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.layer;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.layer.Result;

+

+public class JU_Result {

+	Result result;

+//	@Mock

+//	RV value;

+	int status=0;

+	String details = "details"; 

+	String[] variables;

+	

+	@SuppressWarnings({ "unchecked", "rawtypes" })

+	@Before

+	public void setUp(){

+		result = new Result(result, status, details, variables);

+	}

+

+	@Test

+	public void testPartialContent() {

+		Result Res = result.partialContent(true);

+		System.out.println("Res" +Res);

+		assertEquals(details,Res.toString());

+		

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/local/JU_DataFile.java b/authz-core/src/test/java/org/onap/aaf/authz/local/JU_DataFile.java
new file mode 100644
index 0000000..a5321c5
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/local/JU_DataFile.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.local;

+

+import java.io.File;

+import java.util.ArrayList;

+import java.util.List;

+

+import org.junit.AfterClass;

+import org.junit.Test;

+import org.onap.aaf.authz.local.DataFile;

+import org.onap.aaf.authz.local.DataFile.Token;

+import org.onap.aaf.authz.local.DataFile.Token.Field;

+

+public class JU_DataFile {

+

+	@AfterClass

+	public static void tearDownAfterClass() throws Exception {

+	}

+

+	@Test

+	public void test() throws Exception {

+		File file = new File("../authz-batch/data/v1.dat");

+		DataFile df = new DataFile(file,"r");

+		int count = 0;

+		List<String> list = new ArrayList<String>();

+		try {

+			df.open();

+			Token tok = df.new Token(1024000);

+			Field fld = tok.new Field('|');

+	

+			while(tok.nextLine()) {

+				++count;

+				fld.reset();

+				list.add(fld.at(0));

+			}

+//			Collections.sort(list);

+			for(String s: list) {

+				System.out.println(s);

+

+			}

+		} finally {

+			System.out.printf("%15s:%12d\n","Total",count);

+		}

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/local/JU_TextIndex.java b/authz-core/src/test/java/org/onap/aaf/authz/local/JU_TextIndex.java
new file mode 100644
index 0000000..d8e5c62
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/local/JU_TextIndex.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.local;

+

+import static org.junit.Assert.*;

+

+import java.io.File;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.local.TextIndex;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_TextIndex {

+	TextIndex textIndex;

+	@Mock

+	File file;

+	

+	@Before

+	public void setUp(){

+		textIndex = new TextIndex(file);

+	}

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationException.java b/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationException.java
new file mode 100644
index 0000000..17a76d1
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationException.java
@@ -0,0 +1,49 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_OrganizationException {

+	

+	OrganizationException organizationException;

+	

+	@Before

+	public void setUp(){

+		organizationException = new OrganizationException();

+	}

+	

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationFactory.java b/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationFactory.java
new file mode 100644
index 0000000..ecdc35b
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/authz/org/JU_OrganizationFactory.java
@@ -0,0 +1,65 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.org;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.authz.org.OrganizationFactory;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(PowerMockRunner.class)

+public class JU_OrganizationFactory {

+	private static final String ORG_SLOT = null;

+	OrganizationFactory organizationFactory;

+	@Mock

+	AuthzEnv authzEnvMock;

+	String orgClass="orgclass";

+	String orgNS="orgns";

+	@Before

+	public void setUp(){

+		organizationFactory = new OrganizationFactory();	

+	}

+

+	@SuppressWarnings("static-access")

+	@Test(expected = APIException.class)

+	public void testSetDefaultOrg() throws APIException {

+		//PowerMockito.when(authzEnvMock.slot(ORG_SLOT)).thenReturn("ORG_SLOT");

+		organizationFactory.setDefaultOrg(authzEnvMock, orgClass);

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test(expected = OrganizationException.class)

+	public void testObtain() throws OrganizationException{

+		PowerMockito.when(authzEnvMock.getProperty("Organization."+orgNS)).thenReturn("notnull");

+		organizationFactory.obtain(authzEnvMock, orgNS);

+	}

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CachingFileAccess.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CachingFileAccess.java
new file mode 100644
index 0000000..4248b7c
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CachingFileAccess.java
@@ -0,0 +1,50 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.onap.aaf.cssa.rserv.CachingFileAccess;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+

+@RunWith(PowerMockRunner.class)

+public class JU_CachingFileAccess {

+	CachingFileAccess cachingFileAccess;

+	

+	

+	@Before

+	public void setUp(){

+		cachingFileAccess = new CachingFileAccess(null, null);

+		

+	}

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CodeSetter.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CodeSetter.java
new file mode 100644
index 0000000..04fdbd0
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_CodeSetter.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.cssa.rserv.CodeSetter;

+import org.onap.aaf.cssa.rserv.Route;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(PowerMockRunner.class)

+public class JU_CodeSetter {

+	CodeSetter codeSetter;

+	@Mock

+	Trans transMock;

+	@Mock

+	HttpServletRequest reqMock;

+	@Mock

+	HttpServletResponse respMock;

+	

+	@Before

+	public void setUp(){

+		codeSetter = new CodeSetter(transMock, reqMock, respMock);

+	}

+	

+	@SuppressWarnings("rawtypes")

+	@Mock

+	Route routeMock;

+	

+	@Test

+	public void testMatches() throws IOException, ServletException{

+		boolean result = codeSetter.matches(routeMock);

+		System.out.println("value of res " + codeSetter.matches(routeMock));

+		assertFalse(result);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Pair.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Pair.java
new file mode 100644
index 0000000..1723401
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Pair.java
@@ -0,0 +1,46 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.onap.aaf.cssa.rserv.Pair;

+

+public class JU_Pair {

+	Pair pair;

+	Object x;

+	Object y;

+	

+	@Before

+	public void setUp(){

+		pair = new Pair(x, y);

+	}

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Routes.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Routes.java
new file mode 100644
index 0000000..2942e55
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Routes.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import java.io.IOException;

+import java.util.List;

+

+import javax.servlet.ServletException;

+import javax.servlet.http.HttpServletRequest;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.cssa.rserv.CodeSetter;

+import org.onap.aaf.cssa.rserv.Route;

+import org.onap.aaf.cssa.rserv.Routes;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.Trans;

+

+@RunWith(PowerMockRunner.class)

+public class JU_Routes {

+	Routes routes;

+	@Mock

+	HttpServletRequest reqMock;

+	CodeSetter<Trans> codeSetterMock;

+	Route<Trans> routeObj;

+	

+	@Before

+	public void setUp(){

+		routes = new Routes();

+	}

+	

+	@Test

+	public void testRouteReport(){

+		List listVal = routes.routeReport(); 

+		System.out.println("value of Listval " +listVal);

+		assertNotNull(listVal);

+		

+	}

+	

+	@Test

+	public void testDerive() throws IOException, ServletException{

+		routeObj = routes.derive(reqMock, codeSetterMock);

+		System.out.println("value of routeObj" +routeObj);	

+	}

+	

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_TypedCode.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_TypedCode.java
new file mode 100644
index 0000000..b7e1ae8
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_TypedCode.java
@@ -0,0 +1,53 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.cssa.rserv.RouteReport;

+import org.onap.aaf.cssa.rserv.TypedCode;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_TypedCode {

+	TypedCode typedCode;

+	@Mock

+	RouteReport routeReportMock;

+	

+	@Before

+	public void setUp(){

+		typedCode = new TypedCode();

+	}

+	

+	@Test

+	public void testFirst(){

+		String returnVal = typedCode.first();

+		assertNull(returnVal);

+	}

+	

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Version.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Version.java
new file mode 100644
index 0000000..c97c5a7
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/JU_Version.java
@@ -0,0 +1,58 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Matchers;

+import org.mockito.Mock;

+import org.onap.aaf.cssa.rserv.Version;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_Version {

+	Version version;

+

+	

+	@Before

+	public void setUp(){

+		version = new Version("String");

+	}

+

+	@Test

+	public void testEquals(){

+		boolean val = version.equals(version);

+		System.out.println("value of val " +val);

+		assertTrue(val);

+	}

+	

+	@Test

+	public void testToString(){

+		String strVal = version.toString();

+		System.out.println("value of strVal " +strVal);

+		assertNotNull(strVal);

+	}

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_BetterMatch.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_BetterMatch.java
new file mode 100644
index 0000000..0e2e834
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_BetterMatch.java
@@ -0,0 +1,166 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv.test;

+

+import static junit.framework.Assert.assertEquals;

+import static junit.framework.Assert.assertFalse;

+import static junit.framework.Assert.assertTrue;

+

+import org.junit.Test;

+import org.onap.aaf.cssa.rserv.Match;

+

+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.impl.EnvFactory;

+

+

+public class JU_BetterMatch {

+

+	@Test

+	public void test() {

+		Trans trans = EnvFactory.newTrans();

+		// Bad Match

+		Match bm = new Match("/req/1.0.0/:var");

+

+		assertTrue(bm.match("/req/1.0.0/fred"));

+		assertTrue(bm.match("/req/1.0.0/wilma"));

+		assertTrue(bm.match("/req/1.0.0/wilma/"));

+		assertFalse(bm.match("/req/1.0.0/wilma/bambam"));

+		assertFalse(bm.match("/not/valid/234"));

+		assertFalse(bm.match(""));

+		

+		TimeTaken tt = trans.start("A", Env.SUB);

+		TimeTaken tt2;

+		int i = 0;

+		try {

+			bm = new Match(null);

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match(""));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match(null));

+			tt2.done();

+		} finally {

+			tt.done();

+		}

+		

+	

+		tt = trans.start("B", Env.SUB);

+		i = 0;

+		try {

+			bm = new Match("/req/1.0.0/:urn/:ref");

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/0x12345"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertFalse(bm.match("/req/1.0.0/urn"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/0x12345/"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertFalse(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/0x12345/x"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertFalse(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/0x12345/xyx"));

+		} finally {

+			tt2.done();

+			tt.done();	

+		}

+		

+		tt = trans.start("C", Env.SUB);

+		i = 0;

+		try {

+			String url = "/req/1.0.0/";

+			bm = new Match(url+":urn*");

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			String value = "urn:fsdb,1.0,req,newreq/0x12345";

+			

+			assertTrue(bm.match(url+value));

+			assertEquals("urn:fsdb,1.0,req,newreq/0x12345",bm.param(url+value, ":urn"));

+		} finally {

+			tt2.done();

+			tt.done();	

+		}

+

+		tt = trans.start("D", Env.SUB);

+		i = 0;

+		try {

+			bm = new Match("/req/1.0.0/:urn/:ref*");

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/0x12345"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertFalse(bm.match("/req/1.0.0/urn:fsdb,1.0,req,newreq/"));

+		} finally {

+			tt2.done();

+			tt.done();	

+		}

+

+		tt = trans.start("E", Env.SUB);

+		i = 0;

+		try {

+			bm = new Match("this*");

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("this"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("thisandthat"));

+			tt2.done();

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("this/1.0.0/urn:fsdb,1.0,req,newreq/0x12345/"));

+		} finally {

+			tt2.done();

+			tt.done();	

+		}

+

+		tt = trans.start("F", Env.SUB);

+		i = 0;

+		try {

+			bm = new Match("*");

+			tt2 = trans.start(Integer.toString(++i), Env.SUB);

+			assertTrue(bm.match("<pass>/this"));

+		} finally {

+			tt2.done();

+			tt.done();	

+		}

+		

+		StringBuilder sb = new StringBuilder();

+		trans.auditTrail(0, sb);

+		System.out.println(sb);

+		

+	}

+	

+	@Test

+	public void specialTest() {

+		Match match = new Match("/sample");

+		assertTrue(match.match("/sample"));

+		

+		match = new Match("/lpeer//lpeer/:key/:item*");

+		assertTrue(match.match("/lpeer//lpeer/x/y"));

+		assertFalse(match.match("/lpeer/x/lpeer/x/y"));

+

+	}

+

+}

diff --git a/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_Content.java b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_Content.java
new file mode 100644
index 0000000..4fba0a3
--- /dev/null
+++ b/authz-core/src/test/java/org/onap/aaf/cssa/rserv/test/JU_Content.java
@@ -0,0 +1,132 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.cssa.rserv.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertNotNull;

+import static org.junit.Assert.assertNull;

+

+import java.io.IOException;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.junit.Test;

+import org.onap.aaf.cssa.rserv.HttpCode;

+import org.onap.aaf.cssa.rserv.TypedCode;

+

+import org.onap.aaf.inno.env.TransJAXB;

+import org.onap.aaf.inno.env.impl.EnvFactory;

+

+

+/**

+ * Test the functioning of the "Content" class, which holds, and routes to the right code based on Accept values

+ */

+public class JU_Content {

+	

+

+	@Test

+	public void test() throws Exception {

+		final String BOOL = "Boolean";

+		final String XML = "XML";

+		TransJAXB trans = EnvFactory.newTrans();

+		try {

+		HttpCode<TransJAXB, String> cBool = new HttpCode<TransJAXB,String>(BOOL,"Standard String") {

+			@Override

+			public void handle(TransJAXB trans, HttpServletRequest req, HttpServletResponse resp) {

+				try {

+					resp.getOutputStream().write(context.getBytes());

+				} catch (IOException e) {

+				}

+			}

+		};

+

+		HttpCode<TransJAXB,String> cXML = new HttpCode<TransJAXB,String>(XML, "Standard String") {

+			@Override

+			public void handle(TransJAXB trans, HttpServletRequest req, HttpServletResponse resp) {

+				try {

+					resp.getOutputStream().write(context.getBytes());

+				} catch (IOException e) {

+				}

+			}

+		};

+

+		TypedCode<TransJAXB> ct = new TypedCode<TransJAXB>()

+				.add(cBool,"application/" + Boolean.class.getName()+"+xml;charset=utf8;version=1.1")

+				.add(cXML,"application/xml;q=.9");

+		String expected = "application/java.lang.Boolean+xml;charset=utf8;version=1.1,application/xml;q=0.9";

+		assertEquals(expected,ct.toString());

+

+		//BogusReq req = new BogusReq();

+		//expected = (expected);

+		//HttpServletResponse resp = new BogusResp();

+		

+		assertNotNull("Same Content String and Accept String",ct.prep(trans,expected));

+

+		//expects Null (not run)

+		// A Boolean xml that must have charset utf8 and match version 1.2 or greater

+		expected = ("application/java.lang.Boolean+xml;charset=utf8;version=1.2");

+		assertNull("Accept Minor Version greater than Content Minor Version",ct.prep(trans,expected));

+

+		// Same with (too many) spaces

+		expected = (" application/java.lang.Boolean+xml ; charset = utf8 ; version = 1.2   ");

+		assertNull("Accept Minor Version greater than Content Minor Version",ct.prep(trans,expected));

+

+		//expects Null (not run)

+		expected = ("application/java.lang.Boolean+xml;charset=utf8;version=2.1");

+		assertNull("Major Versions not the same",ct.prep(trans,expected));

+

+		expected = ("application/java.lang.Boolean+xml;charset=utf8;version=1.0");

+		assertNotNull("Content Minor Version is greater than Accept Minor Version",ct.prep(trans,expected));

+

+		expected = "application/java.lang.Squid+xml;charset=utf8;version=1.0,application/xml;q=.9";

+		assertNotNull("2nd one will have to do...",ct.prep(trans,expected));

+

+		expected = "application/java.lang.Boolean+xml;charset=UTF8;version=1.0";

+		assertNotNull("Minor Charset in Caps acceptable",ct.prep(trans,expected));

+

+		// expects no run 

+		expected="application/java.lang.Boolean+xml;charset=MyType;version=1.0";

+		assertNull("Unknown Minor Charset",ct.prep(trans,expected));

+

+		expected="";

+		assertNotNull("Blank Acceptance",ct.prep(trans,expected));

+		

+		expected=null;

+		assertNotNull("Null Acceptance",ct.prep(trans,expected));	

+

+		expected = ("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");

+		assertNotNull("Matches application/xml, and other content not known",ct.prep(trans,expected));

+		

+		// No SemiColon

+		expected = ("i/am/bogus,application/xml");

+		assertNotNull("Match second entry, with no Semis",ct.prep(trans,expected));

+

+ 		} finally {	

+			StringBuilder sb = new StringBuilder();

+			trans.auditTrail(0, sb);

+			System.out.println(sb);

+		}

+	}

+

+}

diff --git a/authz-defOrg/pom.xml b/authz-defOrg/pom.xml
new file mode 100644
index 0000000..6487aaa
--- /dev/null
+++ b/authz-defOrg/pom.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+    <artifactId>parent</artifactId>

+    <version>1.0.0-SNAPSHOT</version>

+    <relativePath>../pom.xml</relativePath>

+  </parent>

+  

+  <artifactId>authz-defOrg</artifactId>

+  <name>Default Organization</name>

+  <description>Example Organization Module</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>0</project.swmVersion>

+	<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+</properties>

+

+  

+  <dependencies>

+    <dependency>

+      <groupId>org.onap.aaf.cadi</groupId>

+      <artifactId>cadi-core</artifactId>

+    </dependency>

+    

+    <dependency>

+      <groupId>org.onap.aaf.authz</groupId>

+      <artifactId>authz-core</artifactId>

+    </dependency>

+    

+    <dependency>

+      		<groupId>javax.mail</groupId>

+      		<artifactId>mail</artifactId>

+    	</dependency> 

+  </dependencies>

+

+	<build>

+		<pluginManagement>

+		<plugins>

+		 <plugin>

+				<groupId>org.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin>

+		</plugins>

+		</pluginManagement>

+	</build>

+	<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+	

+</project>

diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java
new file mode 100644
index 0000000..0352a1a
--- /dev/null
+++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrg.java
@@ -0,0 +1,596 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import javax.mail.Address;

+import javax.mail.Message;

+import javax.mail.MessagingException;

+import javax.mail.Session;

+import javax.mail.Transport;

+import javax.mail.internet.InternetAddress;

+import javax.mail.internet.MimeMessage;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.org.EmailWarnings;

+import org.onap.aaf.authz.org.Executor;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+

+public class DefaultOrg implements Organization {

+	private static final String PROPERTY_IS_REQUIRED = " property is Required";

+	private static final String DOMAIN = "osaaf.com";

+	private static final String REALM = "com.osaaf";

+	private static final String NAME = "Default Organization";

+	private static final String NO_PASS = NAME + " does not support Passwords.  Use AAF";

+	private final String mailHost,mailFromUserId,supportAddress;

+	private String SUFFIX;

+	// Possible ID Pattern

+	private static final String ID_PATTERN = "a-z[a-z0-9]{5-8}@.*";

+

+	public DefaultOrg(AuthzEnv env) throws OrganizationException {

+		String s;

+		mailHost = env.getProperty(s=(REALM + ".mailHost"), null);

+		if(mailHost==null) {

+			throw new OrganizationException(s + PROPERTY_IS_REQUIRED);

+		}

+		supportAddress = env.getProperty(s=(REALM + ".supportEmail"), null);

+		if(supportAddress==null) {

+			throw new OrganizationException(s + PROPERTY_IS_REQUIRED);

+		}

+		

+		String temp = env.getProperty(s=(REALM + ".mailFromUserId"), null);

+		mailFromUserId = temp==null?supportAddress:temp;

+

+		System.getProperties().setProperty("mail.smtp.host",mailHost);

+		System.getProperties().setProperty("mail.user", mailFromUserId);

+		// Get the default Session object.

+		session = Session.getDefaultInstance(System.getProperties());

+

+		SUFFIX='.'+getDomain();

+		

+		try {

+			String defFile;

+			temp=env.getProperty(defFile = (getClass().getName()+".file"));

+			File fIdentities=null;

+			if(temp==null) {

+				temp = env.getProperty("aaf_data_dir");

+				if(temp!=null) {

+					env.warn().log(defFile, "is not defined. Using default: ",temp+"/identities.dat");

+					File dir = new File(temp);

+					fIdentities=new File(dir,"identities.dat");

+					if(!fIdentities.exists()) {

+						env.warn().log("No",fIdentities.getCanonicalPath(),"exists.  Creating.");

+						if(!dir.exists()) {

+							dir.mkdirs();

+						}

+						fIdentities.createNewFile();

+					}

+				}

+			} else {

+				fIdentities = new File(temp);

+				if(!fIdentities.exists()) {

+					String dataDir = env.getProperty("aaf_data_dir");

+					if(dataDir!=null) {

+						fIdentities = new File(dataDir,temp);

+					}

+				}

+			}

+			

+			if(fIdentities!=null && fIdentities.exists()) {

+				identities = new Identities(fIdentities);

+			} else {

+				throw new OrganizationException(fIdentities.getCanonicalPath() + " does not exist.");

+			}

+		} catch (IOException e) {

+			throw new OrganizationException(e);

+		}

+	}

+	

+	// Implement your own Delegation System

+	static final List<String> NULL_DELEGATES = new ArrayList<String>();

+

+	public Identities identities;

+	private boolean dryRun;

+	private Session session;

+	public enum Types {Employee, Contractor, Application, NotActive};

+	private final static Set<String> typeSet;

+	

+	static {

+		typeSet = new HashSet<String>();

+		for(Types t : Types.values()) {

+			typeSet.add(t.name());

+		}

+	}

+	

+	private static final EmailWarnings emailWarnings = new DefaultOrgWarnings();

+

+	@Override

+	public String getName() {

+		return NAME;

+	}

+

+	@Override

+	public String getRealm() {

+		return REALM;

+	}

+

+	@Override

+	public String getDomain() {

+		return DOMAIN;

+	}

+

+	@Override

+	public DefaultOrgIdentity getIdentity(AuthzTrans trans, String id) throws OrganizationException {

+		return new DefaultOrgIdentity(trans,id,this);

+	}

+

+	// Note: Return a null if found; return a String Message explaining why not found. 

+	@Override

+	public String isValidID(String id) {

+		Data data;

+		try {

+			data = identities.find(id, identities.reuse());

+		} catch (IOException e) {

+			return getName() + " could not lookup " + id + ": " + e.getLocalizedMessage();

+		}

+		return data==null?id + "is not an Identity in " + getName():null;

+	}

+

+	@Override

+	public String isValidPassword(String user, String password, String... prev) {

+		// If you have an Organization user/Password scheme, use here, otherwise, just use AAF

+		return NO_PASS;

+	}

+

+	@Override

+	public Set<String> getIdentityTypes() {

+		return typeSet;

+	}

+

+	@Override

+	public Response notify(AuthzTrans trans, Notify type, String url, String[] identities, String[] ccs, String summary, Boolean urgent) {

+		String system = trans.getProperty("CASS_ENV", "");

+

+		ArrayList<String> toList = new ArrayList<String>();

+		Identity identity;

+		if (identities != null) {

+			for (String user : identities) {

+				try {

+					identity = getIdentity(trans, user);

+					if (identity == null) {

+						trans.error().log(

+								"Failure to obtain User " + user + " for "

+										+ getName());

+					} else {

+						toList.add(identity.email());

+					}

+				} catch (Exception e) {

+					trans.error().log(

+							e,

+							"Failure to obtain User " + user + " for "

+									+ getName());

+				}

+			}

+		}

+

+		if (toList.isEmpty()) {

+			trans.error().log("No Users listed to email");

+			return Response.ERR_NotificationFailure;

+		}

+

+		ArrayList<String> ccList = new ArrayList<String>();

+

+		// If we're sending an urgent email, CC the user's supervisor

+		//

+		if (urgent) {

+			trans.info().log("urgent msg for: " + identities[0]);

+			try {

+				List<Identity> supervisors = getApprovers(trans, identities[0]);

+				for (Identity us : supervisors) {

+					trans.info().log("supervisor: " + us.email());

+					ccList.add(us.email());

+				}

+			} catch (Exception e) {

+				trans.error().log(e,

+						"Failed to find supervisor for  " + identities[0]);

+			}

+		}

+

+		if (ccs != null) {

+			for (String user : ccs) {

+				try {

+					identity = getIdentity(trans, user);

+					ccList.add(identity.email());

+				} catch (Exception e) {

+					trans.error().log(

+							e,

+							"Failure to obtain User " + user + " for "

+									+ getName());

+				}

+			}

+		}

+

+		if (summary == null) {

+			summary = "";

+		}

+

+		switch (type) {

+		case Approval:

+			try {

+				sendEmail(trans, toList, ccList,

+						"AAF Approval Notification "

+								+ (system.length() == 0 ? "" : "(ENV: "

+										+ system + ")"),

+						"AAF is the "

+						+ NAME

+						+ "System for Fine-Grained Authorizations.  You are being asked to Approve"

+								+ (system.length() == 0 ? "" : " in the "

+										+ system + " environment")

+								+ " before AAF Actions can be taken.\n\n"

+								+ "Please follow this link: \n\n\t" + url

+								+ "\n\n" + summary, urgent);

+			} catch (Exception e) {

+				trans.error().log(e, "Failure to send Email");

+				return Response.ERR_NotificationFailure;

+			}

+			break;

+		case PasswordExpiration:

+			try {

+				sendEmail(trans,

+						toList,

+						ccList,

+						"AAF Password Expiration Warning "

+								+ (system.length() == 0 ? "" : "(ENV: "

+										+ system + ")"),

+						"AAF is the "

+						+ NAME

+						+ " System for Authorizations.\n\nOne or more passwords will expire soon or have expired"

+								+ (system.length() == 0 ? "" : " in the "

+										+ system + " environment")

+								+ ".\n\nPasswords expired for more than 30 days without action are subject to deletion.\n\n"

+								+ "Please follow each link to add a New Password with Expiration Date. Either are valid until expiration. "

+								+ "Use this time to change the passwords on your system. If issues, reply to this email.\n\n"

+								+ summary, urgent);

+			} catch (Exception e) {

+				trans.error().log(e, "Failure to send Email");

+				return Response.ERR_NotificationFailure;

+			}

+			break;

+

+		case RoleExpiration:

+			try {

+				sendEmail(

+						trans,

+						toList,

+						ccList,

+						"AAF Role Expiration Warning "

+								+ (system.length() == 0 ? "" : "(ENV: "

+										+ system + ")"),

+						"AAF is the "

+						+ NAME

+						+ " System for Authorizations. One or more roles will expire soon"

+								+ (system.length() == 0 ? "" : " in the "

+										+ system + " environment")

+								+ ".\n\nRoles expired for more than 30 days are subject to deletion."

+								+ "Please follow this link the GUI Command line, and either 'extend' or 'del' the user in the role.\n"

+								+ "If issues, reply to this email.\n\n\t" + url

+								+ "\n\n" + summary, urgent);

+			} catch (Exception e) {

+				trans.error().log(e, "Failure to send Email");

+				return Response.ERR_NotificationFailure;

+			}

+			break;

+		default:

+			return Response.ERR_NotImplemented;

+		}

+		return Response.OK;

+	}

+

+	@Override

+	public int sendEmail(AuthzTrans trans, List<String> toList, List<String> ccList, String subject, String body,

+			Boolean urgent) throws OrganizationException {

+		int status = 1;

+		

+		List<String> to = new ArrayList<String>();

+		for(String em : toList) {

+			if(em.indexOf('@')<0) {

+				to.add(new DefaultOrgIdentity(trans, em, this).email());

+			} else {

+				to.add(em);

+			}

+		}

+		

+		List<String> cc = new ArrayList<String>();

+		if(ccList!=null && !ccList.isEmpty()) {

+			for(String em : ccList) {

+				if(em.indexOf('@')<0) {

+					cc.add(new DefaultOrgIdentity(trans, em, this).email());

+				} else {

+					cc.add(em);

+				}

+			}

+		}

+		

+	

+		// for now, I want all emails so we can see what goes out. Remove later

+		if (!ccList.contains(supportAddress)) {

+			ccList.add(supportAddress);

+		}

+

+		try {

+			// Create a default MimeMessage object.

+			MimeMessage message = new MimeMessage(session);

+

+			// Set From: header field of the header.

+			message.setFrom(new InternetAddress(mailFromUserId));

+

+			if (!dryRun) {

+				// Set To: header field of the header. This is a required field

+				// and calling module should make sure that it is not null or

+				// blank

+				message.addRecipients(Message.RecipientType.TO,

+						getAddresses(to));

+

+				// Set CC: header field of the header.

+				if ((ccList != null) && (ccList.size() > 0)) {

+					message.addRecipients(Message.RecipientType.CC,

+							getAddresses(cc));

+				}

+

+				// Set Subject: header field

+				message.setSubject(subject);

+

+				if (urgent) {

+					message.addHeader("X-Priority", "1");

+				}

+

+				// Now set the actual message

+				message.setText(body);

+			} else {

+				// override recipients

+				message.addRecipients(Message.RecipientType.TO,

+						InternetAddress.parse(supportAddress));

+

+				// Set Subject: header field

+				message.setSubject("[TESTMODE] " + subject);

+

+				if (urgent) {

+					message.addHeader("X-Priority", "1");

+				}

+

+				ArrayList<String> newBody = new ArrayList<String>();

+

+				Address temp[] = getAddresses(to);

+				String headerString = "TO:\t" + InternetAddress.toString(temp)

+						+ "\n";

+

+				temp = getAddresses(cc);

+				headerString += "CC:\t" + InternetAddress.toString(temp) + "\n";

+

+				newBody.add(headerString);

+

+				newBody.add("Text: \n");

+

+				newBody.add(body);

+				String outString = "";

+				for (String s : newBody) {

+					outString += s + "\n";

+				}

+

+				message.setText(outString);

+			}

+			// Send message

+			Transport.send(message);

+			status = 0;

+

+		} catch (MessagingException mex) {

+			throw new OrganizationException("Exception send email message "

+					+ mex.getMessage());

+		}

+

+		return status;	

+	}

+

+	/**

+	 * Default Policy is to set to 6 Months for Notification Types.

+	 * add others/change as required

+	 */

+	@Override

+	public Date whenToValidate(Notify type, Date lastValidated) {

+		switch(type) {

+			case Approval:

+			case PasswordExpiration:

+				return null;

+			default:

+				GregorianCalendar gc = new GregorianCalendar();

+				gc.setTime(lastValidated);

+				gc.add(GregorianCalendar.MONTH, 6);  // 6 month policy

+				return gc.getTime();

+		}

+	}

+

+	@Override

+	public GregorianCalendar expiration(GregorianCalendar gc, Expiration exp, String... extra) {

+        GregorianCalendar rv = gc==null?new GregorianCalendar():(GregorianCalendar)gc.clone();

+		switch (exp) {

+			case ExtendPassword:

+				// Extending Password give 5 extra days

+				rv.add(GregorianCalendar.DATE, 5);

+				break;

+			case Future:

+				// Future Requests last 15 days before subject to deletion.

+				rv.add(GregorianCalendar.DATE, 15);

+				break;

+			case Password:

+				// Passwords expire in 90 days

+				rv.add(GregorianCalendar.DATE, 90);

+				break;

+			case TempPassword:

+				// Temporary Passwords last for 12 hours.

+				rv.add(GregorianCalendar.HOUR, 12);

+				break;

+			case UserDelegate:

+				// Delegations expire max in 2 months

+				rv.add(GregorianCalendar.MONTH, 2);

+				break;

+			case UserInRole:

+				// Roles expire in 6 months

+				rv.add(GregorianCalendar.MONTH, 6);

+				break;

+			default:

+				// Unless other wise set, 6 months is default

+				rv.add(GregorianCalendar.MONTH, 6);

+				break;

+		}

+		return rv;

+	}

+

+	@Override

+	public EmailWarnings emailWarningPolicy() {

+		return emailWarnings;

+	}

+

+	/**

+	 * Assume the Supervisor is the Approver.

+	 */

+	@Override

+	public List<Identity> getApprovers(AuthzTrans trans, String user) throws OrganizationException {

+		Identity orgIdentity = getIdentity(trans, user);

+		List<Identity> orgIdentitys = new ArrayList<Identity>();

+		if(orgIdentity!=null) {

+			String supervisorID = orgIdentity.responsibleTo();

+			if (supervisorID.indexOf('@') < 0) {

+			    supervisorID += getDomain();

+			}

+			Identity supervisor = getIdentity(trans, supervisorID);

+			orgIdentitys.add(supervisor);

+		}

+		return orgIdentitys;	

+	}

+

+	@Override

+	public String getApproverType() {

+		return "supervisor";

+	}

+

+	@Override

+	public int startOfDay() {

+		// TODO Auto-generated method stub

+		return 0;

+	}

+

+	@Override

+	public boolean canHaveMultipleCreds(String id) {

+		// External entities are likely mono-password... if you change it, it is a global change.

+		// This is great for people, but horrible for Applications.  

+		//

+		// AAF's Password can have multiple Passwords, each with their own Expiration Date.

+		// For Default Org, we'll assume true for all, but when you add your external

+		// Identity stores, you need to return "false" if they cannot support multiple Passwords like AAF

+		return true;

+	}

+

+	@Override

+	public boolean isValidCred(String id) {

+		if(id.endsWith(SUFFIX)) {

+			return true;

+		}

+		return id.matches(ID_PATTERN);

+	}

+

+	@Override

+	public String validate(AuthzTrans trans, Policy policy, Executor executor, String... vars) throws OrganizationException {

+		switch(policy) {

+			case OWNS_MECHID:

+			case CREATE_MECHID:

+				if(vars.length>0) {

+					Identity requestor = getIdentity(trans, trans.user());

+					if(requestor!=null) {

+						Identity mechid = getIdentity(trans, vars[0]);

+						if(requestor.equals(mechid.owner())) {

+							return null;

+						}

+					}

+				}

+				return trans.user() + " is not the Sponsor of MechID " + vars[0];

+				

+			case CREATE_MECHID_BY_PERM_ONLY:

+				return getName() + " only allows sponsors to create MechIDs";

+				

+			default:

+				return policy.name() + " is unsupported at " + getName();

+		}	

+	}

+

+	@Override

+	public boolean isTestEnv() {

+		return false;

+	}

+

+	@Override

+	public void setTestMode(boolean dryRun) {

+		this.dryRun = dryRun;

+	}

+

+	/**

+	 * Convert the delimiter String into Internet addresses with the default

+	 * delimiter of ";"

+	 * @param strAddress

+	 * @return

+	 */

+	private Address[] getAddresses(List<String> strAddress) throws OrganizationException {

+		return this.getAddresses(strAddress,";");

+	}

+	/**

+	 * Convert the delimiter String into Internet addresses with the 

+	 * delimiter of provided

+	 * @param strAddress

+	 * @param delimiter

+	 * @return

+	 */

+	private Address[] getAddresses(List<String> strAddresses, String delimiter) throws OrganizationException {

+		Address[] addressArray = new Address[strAddresses.size()];

+		int count = 0;

+		for (String addr : strAddresses)

+		{

+            try{

+            	addressArray[count] = new InternetAddress(addr);

+            	count++;

+            }catch(Exception e){

+            	throw new OrganizationException("Failed to parse the email address "+ addr +": "+e.getMessage());

+            }

+        }

+        return addressArray;

+	}

+}

diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java
new file mode 100644
index 0000000..d9641be
--- /dev/null
+++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgIdentity.java
@@ -0,0 +1,147 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import java.io.IOException;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.local.AbsData.Reuse;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+

+import org.onap.aaf.cadi.config.Config;

+

+/**

+ * Org Users are essential representations of Identities within the Org.  Since this is a highly individual 

+ * thing for most Orgs, i.e. some use LDAP, some need feed, some use something else, this object will allow

+ * the Organization to connect to their own Identity systems...

+ * 

+ *

+ */

+public class DefaultOrgIdentity implements Identity {

+    private final static int TIMEOUT = Integer.parseInt(Config.AAF_CONN_TIMEOUT_DEF);

+	

+	private DefaultOrg org;

+	private Data identity;

+	private Identity owner;

+

+	public DefaultOrgIdentity(AuthzTrans trans, String key, DefaultOrg dorg) throws OrganizationException {

+		org = dorg;

+		identity=null;

+		try {

+			org.identities.open(trans, TIMEOUT);

+			try {

+				Reuse r = org.identities.reuse();

+				identity = org.identities.find(key, r);

+				if(identity==null) {

+					identity = Identities.NO_DATA;

+				} else {

+					if("a".equals(identity.status)) {

+						owner = new DefaultOrgIdentity(trans,identity.responsibleTo,org);

+					} else {

+						owner = null;

+					}

+				}

+			} finally {

+				org.identities.close(trans);

+			}

+		} catch (IOException e) {

+			throw new OrganizationException(e);

+		}

+	}

+	

+	@Override

+	public boolean equals(Object b) {

+		if(b instanceof DefaultOrgIdentity) {

+			return identity.id.equals(((DefaultOrgIdentity)b).identity.id);

+		}

+		return false;

+	}

+

+	@Override

+	public String id() {

+		return identity.id;

+	}

+

+	@Override

+	public String fullID() {

+		return identity.id+'@'+org.getDomain();

+	}

+

+	@Override

+	public String type() {

+		switch(identity.status) {

+			case "e": return DefaultOrg.Types.Employee.name();

+			case "c": return DefaultOrg.Types.Contractor.name();

+			case "a": return DefaultOrg.Types.Application.name();

+			case "n": return DefaultOrg.Types.NotActive.name();

+			default:

+				return "Unknown";

+		}

+	}

+

+	@Override

+	public String responsibleTo() {

+		return identity.responsibleTo;

+	}

+

+	@Override

+	public List<String> delegate() {

+		//NOTE:  implement Delegate system, if desired

+		return DefaultOrg.NULL_DELEGATES;

+	}

+

+	@Override

+	public String email() {

+		return identity.email;

+	}

+

+	@Override

+	public String fullName() {

+		return identity.name;

+	}

+

+	@Override

+	public boolean isResponsible() {

+		return "e".equals(identity.status); // Assume only Employees are responsible for Resources.  

+	}

+

+	@Override

+	public boolean isFound() {

+		return identity!=null;

+	}

+

+	@Override

+	public Identity owner() throws OrganizationException {

+		return owner;

+	}

+

+	@Override

+	public Organization org() {

+		return org;

+	}

+

+}

diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java
new file mode 100644
index 0000000..3618379
--- /dev/null
+++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/DefaultOrgWarnings.java
@@ -0,0 +1,64 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import org.onap.aaf.authz.org.EmailWarnings;

+

+public class DefaultOrgWarnings implements EmailWarnings {

+

+	@Override

+    public long credEmailInterval()

+    {

+        return 604800000L; // 7 days in millis 1000 * 86400 * 7

+    }

+    

+	@Override

+    public long roleEmailInterval()

+    {

+        return 604800000L; // 7 days in millis 1000 * 86400 * 7

+    }

+	

+	@Override

+	public long apprEmailInterval() {

+        return 259200000L; // 3 days in millis 1000 * 86400 * 3

+	}

+    

+	@Override

+    public long  credExpirationWarning()

+    {

+        return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30  in milliseconds

+    }

+    

+	@Override

+    public long roleExpirationWarning()

+    {

+        return( 2592000000L ); // One month, in milliseconds 1000 * 86400 * 30  in milliseconds

+    }

+

+	@Override

+    public long emailUrgentWarning()

+    {

+        return( 1209600000L ); // Two weeks, in milliseconds 1000 * 86400 * 14  in milliseconds

+    }

+

+}

diff --git a/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java
new file mode 100644
index 0000000..f7f1319
--- /dev/null
+++ b/authz-defOrg/src/main/java/org/onap/aaf/osaaf/defOrg/Identities.java
@@ -0,0 +1,144 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import java.io.File;

+import java.io.IOException;

+

+import org.onap.aaf.authz.local.AbsData;

+import org.onap.aaf.authz.local.DataFile.Token.Field;

+

+/*

+ * Example User Data file, which can be modified for many different kinds of Data Feeds.

+ * 

+ * Note: This has shown to be extremely effective in AT&T, an acknowledged very large organizations, 

+ * 	     because there is no need to synchronize records.  AAF simply receives a Data Feed in Organization

+ * 		 defined intervals.  (You might want to check for validity, such as size, etc), then is copied into

+ * 		 Data Directory.  You will want to do so first creating a "lock" file.  Assuming the File name is "users.dat",

+ * 		 the Lock File is "users.lock".  

+ * 

+ * 		 After the movement of the Datafile into place, it is best to remove the Index File, then remove the lock file.

+ * 

+ * 		 Note, Any AAF Programs needing this data WILL wait on the Lock file, so you should get fresh Data files

+ *       in a "stage" directory, from WEB, or wherever, and then, after it is correct, do the following as fast as feasible.

+ *       

+ *       	a) lock

+ *          b) copy from stage

+ *          c) remove idx

+ *          d) unlock

+ * 

+ * 	     If the Index File is either non-existent or out of date from the Data File, it will be reindexed, which

+ * 		 has proven to be a very quick function, even with large numbers of entries.

+ * 

+ * This Sample Feed is set for a file with delimiter of "|".  512 is maximum expected line length. The "0" is the

+ *       field offset for the "key" to the record,  which, for user, should be the unique Organization Identity.

+ *       

+ */

+public class Identities extends AbsData {

+	public final static Data NO_DATA = new Data();

+	

+	public Identities(File users) {

+		super(users,'|',512,0);

+	}

+

+	/*

+	 * Example Field Layout.  note, in this example, Application IDs and People IDs are mixed.  You may want to split

+	 *   out AppIDs, choose your own status indicators, or whatever you use.

+	 * 0 - unique ID

+	 * 1 - full name

+	 * 2 - first name

+	 * 3 - last name

+	 * 4 - phone

+	 * 5 - official email

+	 * 6 - employment status e=employee, c=contractor, a=application, n=no longer with company

+	 * 7 - responsible to (i.e Supervisor for People, or AppOwner, if it's an App ID)

+	 */

+	public static class Data {

+		public final String id;

+		public final String name;

+		public final String fname;

+		public final String lname;

+		public final String phone;

+		public final String email;

+		public final String status;

+		public final String responsibleTo;

+		

+		private Data(Field f) {

+			f.reset();

+			id=f.next();

+			name=f.next();

+			fname=f.next();

+			lname=f.next();

+			phone=f.next();

+			email=f.next();

+			status=f.next();

+			responsibleTo =f.next();

+		}

+		

+		private Data() {

+			id = name = fname = lname =

+			phone = email = status = responsibleTo 

+			= "";

+		}

+

+		public String toString() {

+			return  id + '|' +

+					name + '|' +

+					lname + '|' +

+					fname + '|' +

+					phone + '|' +

+					email + '|' +

+					status + '|' +

+					responsibleTo;

+		}

+		

+		// Here, make up your own Methods which help you easily determine your Organization's structure

+		// in your Organization Object

+        public boolean hasStatus(String possible) {

+            return possible.contains(status);

+	    }

+

+	    public boolean isEmployee() {

+	            return "e".equals(status);

+	    }

+	

+	    public boolean isContractor() {

+	            return "c".equals(status);

+	    }

+	

+	    public boolean isApplication() {

+	            return "a".equals(status);

+	    }

+	}

+	

+    public Data find(Object key,Reuse r) throws IOException {

+        r.getFieldData().reset();

+        // These are new, to allow for Thread Safety

+        int rec = ti.find(key,r.getTokenData(),r.getFieldData(),0);

+        if(rec<0) {

+            return null;

+        }

+        r.getTokenData().pos(rec);

+        return new Data(r.getFieldData());

+    }

+}

diff --git a/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrd/test/JU_Identities.java b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrd/test/JU_Identities.java
new file mode 100644
index 0000000..064d095
--- /dev/null
+++ b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrd/test/JU_Identities.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+/**

+ * 

+ */

+package org.onap.aaf.osaaf.defOrd.test;

+

+import java.io.File;

+import java.io.IOException;

+

+import org.junit.After;

+import org.junit.AfterClass;

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.local.AbsData.Reuse;

+import org.onap.aaf.osaaf.defOrg.Identities;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+

+/**

+ *

+ */

+public class JU_Identities {

+

+	private static final String DATA_IDENTITIES = "../opt/app/aaf/data/identities.dat";

+	private static File fids;

+	private static Identities ids;

+	private static AuthzEnv env;

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@BeforeClass

+	public static void setUpBeforeClass() throws Exception {

+		env = new AuthzEnv();

+		AuthzTrans trans = env.newTransNoAvg();

+		// Note: utilize TimeTaken, from trans.start if you want to time.

+		fids = new File(DATA_IDENTITIES);

+		if(fids.exists()) {

+			ids = new Identities(fids);

+			ids.open(trans, 5000);

+		} else {

+			

+			throw new Exception("Data File for Tests, \"" + DATA_IDENTITIES 

+					+ "\" must exist before test can run. (Current dir is " + System.getProperty("user.dir") + ")");

+		}

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@AfterClass

+	public static void tearDownAfterClass() throws Exception {

+		AuthzTrans trans = env.newTransNoAvg();

+		if(ids!=null) {

+			ids.close(trans);

+		}

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@Before

+	public void setUp() throws Exception {

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@After

+	public void tearDown() throws Exception {

+	}

+ 

+	@Test

+	public void test() throws IOException {

+		Reuse reuse = ids.reuse(); // this object can be reused within the same thread.

+		Data id = ids.find("osaaf",reuse);

+		Assert.assertNotNull(id);

+		System.out.println(id);

+

+		id = ids.find("mmanager",reuse);

+		Assert.assertNotNull(id);

+		System.out.println(id);

+

+		//TODO Fill out JUnit with Tests of all Methods in "Data id"

+	}

+

+}

diff --git a/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrg.java b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrg.java
new file mode 100644
index 0000000..19acfdb
--- /dev/null
+++ b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrg.java
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import static org.junit.Assert.*;

+

+import java.io.File;

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.regex.Matcher;

+

+import javax.mail.Address;

+import javax.mail.internet.InternetAddress;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Matchers;

+import org.mockito.Mock;

+import org.mockito.MockitoAnnotations;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.org.Executor;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.authz.org.Organization.Policy;

+import org.onap.aaf.osaaf.defOrg.DefaultOrg;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_DefaultOrg {

+

+DefaultOrg defaultOrg;

+//private DefaultOrg defaultOrgMock;

+@Mock

+AuthzEnv authzEnvMock;

+

+private static final String PROPERTY_IS_REQUIRED = " property is Required";

+private static final String DOMAIN = "osaaf.com";

+private static final String REALM = "com.osaaf";

+private static final String NAME = "Default Organization";

+private static final String NO_PASS = NAME + " does not support Passwords.  Use AAF";

+String mailHost,mailFromUserId,supportAddress;

+private String SUFFIX;

+String s;

+String defFile;

+@Mock

+File fIdentitiesMock;

+

+@Before

+public void setUp() throws OrganizationException{

+	MockitoAnnotations.initMocks(this);

+	PowerMockito.when(authzEnvMock.getProperty(s=(REALM + ".mailHost"), null)).thenReturn("hello");

+	PowerMockito.when(authzEnvMock.getProperty(s=(REALM + ".supportEmail"), null)).thenReturn("notnull");

+	PowerMockito.when(authzEnvMock.getProperty(Matchers.anyString())).thenReturn("C:/Users/sv8675/Desktop/AAF-Code-Sai/AAF-master/authz/authz-defOrg/src/main/java/test.txt");

+	PowerMockito.when(fIdentitiesMock.exists()).thenReturn(true);

+	//PowerMockito.when((fIdentitiesMock!=null && fIdentitiesMock.exists())).thenReturn(true);

+	defaultOrg = new DefaultOrg(authzEnvMock);

+}

+

+@Test    //(expected=OrganizationException.class)

+public void test() throws OrganizationException{

+	//PowerMockito.when(authzEnvMock.getProperty(Matchers.anyString())).thenReturn(" ");

+	//defaultOrg = new DefaultOrg(authzEnvMock);

+	assertTrue(true);

+}

+

+@Test

+public void testIsValidID(){	

+	String Result = defaultOrg.isValidID(Matchers.anyString());

+	System.out.println("value of res " +Result);

+	assertNotNull(Result);	

+}

+

+@Mock

+AuthzTrans authzTransMock;

+

+

+}

diff --git a/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgIdentity.java b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgIdentity.java
new file mode 100644
index 0000000..5f915d5
--- /dev/null
+++ b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgIdentity.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.MockitoAnnotations;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.org.OrganizationException;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.osaaf.defOrg.DefaultOrg;

+import org.onap.aaf.osaaf.defOrg.DefaultOrgIdentity;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_DefaultOrgIdentity {

+

+	private DefaultOrgIdentity defaultOrgIdentity;

+	private DefaultOrgIdentity defaultOrgIdentityMock;

+	

+	@Mock

+	AuthzTrans authzTransMock;

+	

+	String key="key";

+	

+	@Mock

+	private DefaultOrg defaultOrgMock;

+	@Mock

+	private Data dataMock;

+	@Mock

+	private Identity identityMock;

+	

+	@Before

+	public void setUp() throws OrganizationException{

+		MockitoAnnotations.initMocks(this);

+		defaultOrgIdentityMock = PowerMockito.mock(DefaultOrgIdentity.class);

+	}

+	

+	@Test

+	public void testEquals(){

+		Object b = null;

+		Boolean res = defaultOrgIdentityMock.equals(b);

+		System.out.println("value of res " +res);

+	}

+	

+}

diff --git a/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgWarnings.java b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgWarnings.java
new file mode 100644
index 0000000..6066594
--- /dev/null
+++ b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_DefaultOrgWarnings.java
@@ -0,0 +1,84 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.osaaf.defOrg;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.MockitoAnnotations;

+import org.onap.aaf.osaaf.defOrg.DefaultOrgWarnings;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_DefaultOrgWarnings {

+	

+	private DefaultOrgWarnings defaultOrgWarningsMock;

+	private DefaultOrgWarnings defaultOrgWarnings;

+	

+	

+	@Before

+	public void setUp(){

+		MockitoAnnotations.initMocks(this);

+		

+		defaultOrgWarningsMock = PowerMockito.mock(DefaultOrgWarnings.class);

+		

+		defaultOrgWarnings = new DefaultOrgWarnings();

+	}

+

+	

+	@Test

+	public void testApprEmailInterval() {

+		

+		assertEquals(259200000, defaultOrgWarnings.apprEmailInterval() );

+	}

+	

+	@Test

+	public void testCredEmailInterval() {

+		assertEquals(604800000, defaultOrgWarnings.credEmailInterval());

+		

+	}

+	

+	@Test

+	public void testCredExpirationWarning() {

+		assertEquals(2592000000L, defaultOrgWarnings.credExpirationWarning());

+	}

+	

+	@Test

+	public void testEmailUrgentWarning() {

+		assertEquals(1209600000L, defaultOrgWarnings.emailUrgentWarning());

+	}

+	

+	@Test

+	public void testRoleEmailInterval() {

+		assertEquals(604800000L, defaultOrgWarnings.roleEmailInterval());

+	}

+	

+	@Test

+	public void testRoleExpirationWarning() {

+		assertEquals(2592000000L, defaultOrgWarnings.roleExpirationWarning());

+	}

+

+}

diff --git a/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_Identities.java b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_Identities.java
new file mode 100644
index 0000000..78551c0
--- /dev/null
+++ b/authz-defOrg/src/test/java/org/onap/aaf/osaaf/defOrg/JU_Identities.java
@@ -0,0 +1,111 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+/**

+ * 

+ */

+package org.onap.aaf.osaaf.defOrg;

+

+import java.io.File;

+import java.io.IOException;

+

+import org.junit.After;

+import org.junit.AfterClass;

+import org.junit.Assert;

+import org.junit.Before;

+import org.junit.BeforeClass;

+import org.junit.Test;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.local.AbsData.Reuse;

+import org.onap.aaf.osaaf.defOrg.Identities;

+import org.onap.aaf.osaaf.defOrg.Identities.Data;

+

+/**

+ *

+ */

+public class JU_Identities {

+

+	private static final String DATA_IDENTITIES = "../opt/app/aaf/data/identities.dat";

+	private static File fids;

+	private static Identities ids;

+	private static AuthzEnv env;

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@BeforeClass

+	public static void setUpBeforeClass() throws Exception {

+		env = new AuthzEnv();

+		AuthzTrans trans = env.newTransNoAvg();

+		// Note: utilize TimeTaken, from trans.start if you want to time.

+		fids = new File(DATA_IDENTITIES);

+		if(fids.exists()) {

+			ids = new Identities(fids);

+			ids.open(trans, 5000);

+		} else {

+			

+			throw new Exception("Data File for Tests, \"" + DATA_IDENTITIES 

+					+ "\" must exist before test can run. (Current dir is " + System.getProperty("user.dir") + ")");

+		}

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@AfterClass

+	public static void tearDownAfterClass() throws Exception {

+		AuthzTrans trans = env.newTransNoAvg();

+		if(ids!=null) {

+			ids.close(trans);

+		}

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@Before

+	public void setUp() throws Exception {

+	}

+

+	/**

+	 * @throws java.lang.Exception

+	 */

+	@After

+	public void tearDown() throws Exception {

+	}

+ 

+	@Test

+	public void test() throws IOException {

+		Reuse reuse = ids.reuse(); // this object can be reused within the same thread.

+		Data id = ids.find("osaaf",reuse);

+		Assert.assertNotNull(id);

+		System.out.println(id);

+

+		id = ids.find("mmanager",reuse);

+		Assert.assertNotNull(id);

+		System.out.println(id);

+

+		//TODO Fill out JUnit with Tests of all Methods in "Data id"

+	}

+

+}

diff --git a/authz-fs/pom.xml b/authz-fs/pom.xml
new file mode 100644
index 0000000..bef8442
--- /dev/null
+++ b/authz-fs/pom.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-fs</artifactId>

+	<name>Authz File Server</name>

+	<description>Independent FileServer via HTTP (not S) for Public Files (i.e. CRLs)</description>

+		<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>true</maven.test.failure.ignore>

+		<project.swmVersion>9</project.swmVersion>

+			<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+	</properties>

+	

+		

+	<dependencies>

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-core</artifactId>

+        </dependency>

+        <dependency> 

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-core</artifactId>

+		</dependency>

+		<dependency>

+		    <groupId>com.att.aft</groupId>

+  			<artifactId>dme2</artifactId>

+  		</dependency>

+	</dependencies>

+	

+	<build>

+		<plugins>

+            <plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-jar-plugin</artifactId>

+					<configuration>

+	                	<includes>

+	                		<include>**/*.class</include>

+	                	</includes>

+					</configuration>

+					<version>2.3.1</version>

+				</plugin>

+

+			    <plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<configuration>

+						<skip>true</skip>

+					</configuration>

+			    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin>

+			</plugins>

+

+	</build>

+<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+</project>

diff --git a/authz-fs/src/main/config/FileServer.props b/authz-fs/src/main/config/FileServer.props
new file mode 100644
index 0000000..ed1506e
--- /dev/null
+++ b/authz-fs/src/main/config/FileServer.props
@@ -0,0 +1,20 @@
+##
+## AUTHZ API (authz-service) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+DMEServiceName=service=com.att.authz.authz-fs/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_FS_PORT_RANGE_
+AFT_DME2_SSL_ENABLE=false
+AFT_DME2_DISABLE_PERSISTENT_CACHE=true
+
+CFA_WebPath=_ROOT_DIR_/data
+CFA_ClearCommand=FmzYPpMY918MwE1hyacoiFSt
+CFA_MaxSize=2000000
\ No newline at end of file
diff --git a/authz-fs/src/main/config/log4j.properties b/authz-fs/src/main/config/log4j.properties
new file mode 100644
index 0000000..65a4ca7
--- /dev/null
+++ b/authz-fs/src/main/config/log4j.properties
@@ -0,0 +1,90 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}

+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.INIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+

+log4j.appender.FS=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.FS.File=logs/${LOG4J_FILENAME_authz}

+log4j.appender.FS.DatePattern='.'yyyy-MM-dd

+#log4j.appender.FS.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.FS.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.FS.layout=org.apache.log4j.PatternLayout 

+log4j.appender.FS.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %p [%c] %m %n

+

+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}

+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.AUDIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.AUDIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.AUDIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.TRACE=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.TRACE.File=logs/${LOG4J_FILENAME_trace}

+log4j.appender.TRACE.DatePattern='.'yyyy-MM-dd

+#log4j.appender.TRACE.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.TRACE.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.TRACE.layout=org.apache.log4j.PatternLayout 

+log4j.appender.TRACE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.stdout=org.apache.log4j.ConsoleAppender

+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN

+log4j.logger.org.apache=WARN,INIT

+log4j.logger.dme2=WARN,INIT

+log4j.logger.init=INFO,INIT

+log4j.logger.authz=_LOG4J_LEVEL_,FS

+log4j.logger.audit=INFO,AUDIT

+log4j.logger.trace=TRACE,TRACE

+

+

diff --git a/authz-fs/src/main/config/lrm-authz-fs.xml b/authz-fs/src/main/config/lrm-authz-fs.xml
new file mode 100644
index 0000000..b5d1ffd
--- /dev/null
+++ b/authz-fs/src/main/config/lrm-authz-fs.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">

+    <ns2:ManagedResource>

+        <ResourceDescriptor>

+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>

+            <ResourceVersion>

+                <Major>_MAJOR_VER_</Major>

+                <Minor>_MINOR_VER_</Minor>

+                <Patch>_PATCH_VER_</Patch>                

+            </ResourceVersion>

+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>

+        </ResourceDescriptor>

+        <ResourceType>Java</ResourceType>

+        <ResourcePath>com.att.authz.fs.FileServer</ResourcePath>

+        <ResourceProps>

+            <Tag>process.workdir</Tag>

+            <Value>_ROOT_DIR_</Value>

+        </ResourceProps>    	       

+        <ResourceProps>

+            <Tag>jvm.version</Tag>

+            <Value>1.8</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.args</Tag>

+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.classpath</Tag>

+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.min</Tag>

+            <Value>1024m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.max</Tag>

+            <Value>2048m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>start.class</Tag>

+            <Value>com.att.authz.fs.FileServer</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stdout.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stderr.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>

+        </ResourceProps>

+        <ResourceOSID>aft</ResourceOSID>

+        <ResourceStartType>AUTO</ResourceStartType>

+        <ResourceStartPriority>2</ResourceStartPriority>

+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>

+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        

+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>

+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>

+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>

+    </ns2:ManagedResource>

+</ns2:ManagedResourceList>

diff --git a/authz-fs/src/main/data/test.html b/authz-fs/src/main/data/test.html
new file mode 100644
index 0000000..7ea7302
--- /dev/null
+++ b/authz-fs/src/main/data/test.html
@@ -0,0 +1,42 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+<html>

+  <head>                                 <!-- begin head -->

+    <meta charset="utf-8">

+    <title>AT&amp;T Authentication/Authorization Tool</title>

+    <!-- 

+    <link rel="stylesheet" href="_AUTHZ_GUI_URL_/theme/aaf5.css">

+    <script type="text/javascript" src="_AUTHZ_GUI_URL_/theme/comm.js"></script>

+    <script type="text/javascript" src="_AUTHZ_GUI_URL_/theme/console.js"></script>

+    <script type="text/javascript" src="_AUTHZ_GUI_URL_/theme/common.js"></script>

+    <link rel="stylesheet" href="_AUTHZ_GUI_URL_/theme/aaf5Desktop.css">

+     -->

+  </head>                                <!-- end head -->

+  <body>                                 <!-- begin body -->

+    <header>                             <!-- begin header -->

+            <h1>AT&amp;T Auth Tool on _ENV_CONTEXT_</h1>

+      <p id="version">AAF Version: _ARTIFACT_VERSION_</p>

+    </header>

+  <h1>Success for File Server Access</h1>

+  </body>

+</html>

diff --git a/authz-fs/src/main/java/org/onap/aaf/authz/fs/FileServer.java b/authz-fs/src/main/java/org/onap/aaf/authz/fs/FileServer.java
new file mode 100644
index 0000000..0a8547f
--- /dev/null
+++ b/authz-fs/src/main/java/org/onap/aaf/authz/fs/FileServer.java
@@ -0,0 +1,156 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.fs;

+

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+

+import java.io.IOException;

+import java.io.InputStream;

+import java.net.URL;

+import java.util.ArrayList;

+import java.util.EnumSet;

+import java.util.List;

+import java.util.Properties;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.env.AuthzTransOnlyFilter;

+import org.onap.aaf.cssa.rserv.CachingFileAccess;

+import org.onap.aaf.cssa.rserv.RServlet;

+

+import com.att.aft.dme2.api.DME2Manager;

+import com.att.aft.dme2.api.DME2Server;

+import com.att.aft.dme2.api.DME2ServerProperties;

+import com.att.aft.dme2.api.DME2ServiceHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.util.DME2ServletHolder;

+import org.onap.aaf.inno.env.APIException;

+

+

+public class FileServer extends RServlet<AuthzTrans>  {

+	public FileServer(final AuthzEnv env) throws APIException, IOException {

+		try {

+			///////////////////////  

+			// File Server 

+			///////////////////////

+			

+			CachingFileAccess<AuthzTrans> cfa = new CachingFileAccess<AuthzTrans>(env);

+			route(env,GET,"/:key", cfa); 

+			route(env,GET,"/:key/:cmd", cfa); 

+			///////////////////////

+	

+	

+		} catch (Exception e) {

+			e.printStackTrace();

+		}

+	}

+	

+	public static void main(String[] args) {

+		try {

+			// Load Properties from authFramework.properties.  Needed for DME2 and AuthzEnv

+			Properties props = new Properties();

+			URL rsrc = ClassLoader.getSystemResource("FileServer.props");

+			if(rsrc==null) {

+				System.err.println("Folder containing FileServer.props must be on Classpath");

+				System.exit(1);

+			}

+			InputStream is = rsrc.openStream();

+			try {

+				props.load(is);

+			} finally {

+				is.close();

+			}

+			

+			// Load Properties into AuthzEnv

+			AuthzEnv env = new AuthzEnv(props); 

+			env.setLog4JNames("log4j.properties","authz","fs","audit","init",null);

+			

+			// AFT Discovery Libraries only read System Props

+			env.loadToSystemPropsStartsWith("AFT_","DME2_");

+			env.init().log("DME2 using " + env.getProperty("DMEServiceName","unknown") + " URI");

+			

+			// Start DME2 (DME2 needs Properties form of props)

+		    DME2Manager dme2 = new DME2Manager("RServDME2Manager",props);

+		    

+		    DME2ServiceHolder svcHolder;

+		    List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();

+		    svcHolder = new DME2ServiceHolder();

+		    String serviceName = env.getProperty("DMEServiceName",null);

+			if(serviceName!=null) {

+		    	svcHolder.setServiceURI(serviceName);

+		        svcHolder.setManager(dme2);

+		        svcHolder.setContext("/");

+		        

+		        FileServer fs = new FileServer(env);

+		        DME2ServletHolder srvHolder = new DME2ServletHolder(fs);

+		        srvHolder.setContextPath("/*");

+		        slist.add(srvHolder);

+		        

+		        EnumSet<RequestDispatcherType> edlist = EnumSet.of(

+		        		RequestDispatcherType.REQUEST,

+		        		RequestDispatcherType.FORWARD,

+		        		RequestDispatcherType.ASYNC

+		        		);

+

+		        ///////////////////////

+		        // Apply Filters

+		        ///////////////////////

+		        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();

+		        

+		    	// Need TransFilter

+		    	flist.add(new DME2FilterHolder(new AuthzTransOnlyFilter(env),"/*",edlist));

+		        svcHolder.setFilters(flist);

+		        svcHolder.setServletHolders(slist);

+		        

+		        DME2Server dme2svr = dme2.getServer();

+		        DME2ServerProperties dsprops = dme2svr.getServerProperties();

+		        dsprops.setGracefulShutdownTimeMs(1000);

+

+		        env.init().log("Starting AAF FileServer with Jetty/DME2 server...");

+		        dme2svr.start();

+		        try {

+//		        	if(env.getProperty("NO_REGISTER",null)!=null)

+		        	dme2.bindService(svcHolder);

+		        	env.init().log("DME2 is available as HTTP"+(dsprops.isSslEnable()?"/S":""),"on port:",dsprops.getPort());

+

+		            while(true) { // Per DME2 Examples...

+		            	Thread.sleep(5000);

+		            }

+		        } catch(InterruptedException e) {

+		            env.init().log("AAF Jetty Server interrupted!");

+		        } catch(Exception e) { // Error binding service doesn't seem to stop DME2 or Process

+		            env.init().log(e,"DME2 Initialization Error");

+		        	dme2svr.stop();

+		        	System.exit(1);

+		        }

+			} else {

+				env.init().log("Properties must contain DMEServiceName");

+			}

+

+		} catch (Exception e) {

+			e.printStackTrace(System.err);

+			System.exit(1);

+		}

+	}

+}

diff --git a/authz-fs/src/test/java/org/onap/aaf/authz/fs/JU_FileServer.java b/authz-fs/src/test/java/org/onap/aaf/authz/fs/JU_FileServer.java
new file mode 100644
index 0000000..88858e7
--- /dev/null
+++ b/authz-fs/src/test/java/org/onap/aaf/authz/fs/JU_FileServer.java
@@ -0,0 +1,83 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.fs;

+

+import static org.junit.Assert.*;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+

+import java.io.File;

+import java.io.IOException;

+import java.net.URL;

+import java.util.Properties;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.InjectMocks;

+import org.mockito.Matchers;

+import org.mockito.Mock;

+import org.mockito.Mockito;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.fs.*;

+import org.onap.aaf.cssa.rserv.CachingFileAccess;

+import org.powermock.api.mockito.PowerMockito;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.inno.env.APIException;

+

+@RunWith(MockitoJUnitRunner.class)

+public class JU_FileServer {	

+	@Mock

+	AuthzEnv authzEnvMock;

+	AuthzEnv authzEnv = new AuthzEnv();

+	

+	@Before

+	public void setUp() throws APIException, IOException{

+

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testMain() throws Exception{

+		

+		String[] args = null;

+		Properties props = new Properties();

+		ClassLoader classLoader = getClass().getClassLoader();

+		File file = new File(classLoader.getResource("FileServer.props").getFile());

+

+//PowerMockito.whenNew(Something.class).withArguments(argument).thenReturn(mockSomething);

+		//			env.setLog4JNames("log4j.properties","authz","fs","audit","init",null);

+    // PowerMockito.whenNew(AuthzEnv.class).withArguments(props).thenReturn(authzEnvMock);

+   //  PowerMockito.doNothing().when(authzEnvMock.setLog4JNames(Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString()));

+  // PowerMockito.when(new AuthzEnv(props)).thenReturn(authzEnvMock);

+		//PowerMockito.doNothing().when(authzEnv).setLog4JNames(Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString(), Matchers.anyString());

+	//PowerMockito.doNothing().when(authzEnvMock).setLog4JNames(" "," "," "," "," "," ");

+

+		FileServer.main(args);

+		//assertTrue(true);

+		

+	}

+	

+}

diff --git a/authz-gui/pom.xml b/authz-gui/pom.xml
new file mode 100644
index 0000000..a513a31
--- /dev/null
+++ b/authz-gui/pom.xml
@@ -0,0 +1,232 @@
+<?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-gui</artifactId>
+	<name>Authz GUI (Mobile First)</name>
+	<description>GUI for Authz Management</description>
+		<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>true</maven.test.failure.ignore>
+		<project.swmVersion>28</project.swmVersion>
+	</properties>
+	
+		
+	<dependencies>
+        <dependency>
+            <groupId>com.att.authz</groupId>
+            <artifactId>authz-core</artifactId>
+            <exclusions>
+			  <exclusion> 
+					<groupId>javax.servlet</groupId>
+       			<artifactId>servlet-api</artifactId>
+       		   </exclusion>
+		    </exclusions> 
+        </dependency>
+	    
+        <dependency>
+            <groupId>com.att.authz</groupId>
+            <artifactId>authz-client</artifactId>
+        </dependency>
+        
+     <!--    <dependency>
+            <groupId>com.att.authz</groupId>
+            <artifactId>authz-att</artifactId>
+        </dependency>    --> 
+        
+        
+        <dependency>
+            <groupId>com.att.authz</groupId>
+            <artifactId>authz-cmd</artifactId>
+            <exclusions>
+		      <exclusion> 
+		        <groupId>org.slf4j</groupId>
+		        <artifactId>slf4j-log4j12</artifactId>
+		      </exclusion>
+		      <exclusion> 
+		        <groupId>log4j</groupId>
+		        <artifactId>log4j</artifactId>
+		      </exclusion>
+            </exclusions>
+        </dependency>
+
+		<dependency> 
+			<groupId>org.onap.aaf.cadi</groupId>
+			<artifactId>cadi-aaf</artifactId>
+		</dependency>
+
+		<dependency> 
+			<groupId>org.onap.aaf.cadi</groupId>
+			<artifactId>cadi-tguard</artifactId>
+		</dependency>
+
+		<dependency> 
+			<groupId>org.onap.aaf.cadi</groupId>
+			<artifactId>cadi-client</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>gso</groupId>
+			<artifactId>GLCookieDecryption</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>org.onap.aaf.inno</groupId>
+			<artifactId>xgen</artifactId>
+		</dependency>
+		
+	</dependencies>
+	
+	<build>
+		<plugins>
+            <plugin>
+			<groupId>org.apache.maven.plugins</groupId>
+			<artifactId>maven-jar-plugin</artifactId>
+				<configuration>
+                	<includes>
+                		<include>**/*.class</include>
+                	</includes>
+				</configuration>
+				<version>2.3.1</version>
+			</plugin>
+	
+			<plugin>
+		      <artifactId>maven-assembly-plugin</artifactId>
+		      <executions>
+		      	<execution>
+		      		<id>swm</id>
+		      		<phase>package</phase>
+		      		<goals>
+		      			<goal>single</goal>
+		      		</goals>
+		      		<configuration>
+		      			<finalName>authz-gui-${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-deploy-plugin</artifactId>
+				<configuration>
+					<skip>true</skip>
+				</configuration>
+		    </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>
+		<pluginManagement>
+			<plugins/>
+		</pluginManagement>
+	</build>
+
+	<distributionManagement>
+    		<snapshotRepository>
+      			<id>ossrhdme</id>
+      			<url>https://oss.sonatype.org/content/repositories/snapshots</url>
+    		</snapshotRepository>
+    		<repository>
+      			<id>ossrhdme</id>
+      			<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
+    		</repository>
+	</distributionManagement>
+	
+	<scm>
+		<connection>https://github.com/att/AAF.git</connection>
+		<developerConnection>${project.scm.connection}</developerConnection>
+		<url>http://github.com/att/AAF/tree/master</url>
+	</scm>
+</project>
diff --git a/authz-gui/src/main/config/authGUI.props b/authz-gui/src/main/config/authGUI.props
new file mode 100644
index 0000000..d90e440
--- /dev/null
+++ b/authz-gui/src/main/config/authGUI.props
@@ -0,0 +1,34 @@
+##
+## AUTHZ GUI (authz-gui) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+##DME2 related parameters
+DMEServiceName=service=com.att.authz.authz-gui/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_GUI_PORT_RANGE_
+
+# Turn on both AAF TAF & LUR 2.0                                                
+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+
+## URLs
+aaf_url.gui_onboard=https://wiki.web.att.com/display/aaf/OnBoarding
+aaf_url.aaf_help=http://wiki.web.att.com/display/aaf
+aaf_url.cadi_help=http://wiki.web.att.com/display/cadi
+aaf_tools=swm,scamper,dme2,soacloud
+aaf_url.tool.swm=http://wiki.web.att.com/display/swm
+aaf_url.tool.scamper=https://wiki.web.att.com/display/scamper/Home
+aaf_url.tool.soacloud=https://wiki.web.att.com/display/soacloud/SOA+Cloud+Management+Platform
+aaf_url.tool.dme2=https://wiki.web.att.com/display/soacloud/User+Guide+-+DME2
+
+
diff --git a/authz-gui/src/main/config/log4j.properties b/authz-gui/src/main/config/log4j.properties
new file mode 100644
index 0000000..e1c9db7
--- /dev/null
+++ b/authz-gui/src/main/config/log4j.properties
@@ -0,0 +1,57 @@
+###############################################################################
+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}
+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd
+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 
+log4j.appender.INIT.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.GUI=org.apache.log4j.DailyRollingFileAppender 
+log4j.appender.GUI.File=_LOG_DIR_/${LOG4J_FILENAME_gui}
+log4j.appender.GUI.DatePattern='.'yyyy-MM-dd
+#log4j.appender.GUI.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.GUI.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.GUI.layout=org.apache.log4j.PatternLayout 
+log4j.appender.GUI.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}
+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd
+#log4j.appender.GUI.MaxFileSize=_MAX_LOG_FILE_SIZE_
+#log4j.appender.GUI.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_
+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 
+log4j.appender.AUDIT.layout.ConversionPattern=%d %p [%c] %m %n
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %m %n
+
+# General Apache libraries
+log4j.rootLogger=WARN
+log4j.logger.org.apache=WARN,INIT
+log4j.logger.dme2=WARN,INIT
+log4j.logger.init=INFO,INIT
+log4j.logger.gui=_LOG4J_LEVEL_,GUI
+log4j.logger.audit=INFO,AUDIT
+
diff --git a/authz-gui/src/main/config/lrm-authz-gui.xml b/authz-gui/src/main/config/lrm-authz-gui.xml
new file mode 100644
index 0000000..f9a45e9
--- /dev/null
+++ b/authz-gui/src/main/config/lrm-authz-gui.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+    Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ -->
+
+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">
+    <ns2:ManagedResource>
+        <ResourceDescriptor>
+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>
+            <ResourceVersion>
+                <Major>_MAJOR_VER_</Major>
+                <Minor>_MINOR_VER_</Minor>
+                <Patch>_PATCH_VER_</Patch>                
+            </ResourceVersion>
+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>
+        </ResourceDescriptor>
+        <ResourceType>Java</ResourceType>
+        <ResourcePath>com.att.authz.gui.AuthGUI</ResourcePath>
+        <ResourceProps>
+            <Tag>process.workdir</Tag>
+            <Value>_ROOT_DIR_</Value>
+        </ResourceProps>    	       
+        <ResourceProps>
+            <Tag>jvm.version</Tag>
+            <Value>1.8</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.args</Tag>
+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.classpath</Tag>
+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.heap.min</Tag>
+            <Value>512m</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>jvm.heap.max</Tag>
+            <Value>2048m</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>start.class</Tag>
+            <Value>com.att.authz.gui.AuthGUI</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>stdout.redirect</Tag>
+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>
+        </ResourceProps>
+        <ResourceProps>
+            <Tag>stderr.redirect</Tag>
+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>
+        </ResourceProps>
+        <ResourceOSID>aft</ResourceOSID>
+        <ResourceStartType>AUTO</ResourceStartType>
+        <ResourceStartPriority>3</ResourceStartPriority>
+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>
+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        
+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>
+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>
+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>
+    </ns2:ManagedResource>
+</ns2:ManagedResourceList>
diff --git a/authz-gui/src/main/java/com/att/authz/cui/CUI.java b/authz-gui/src/main/java/com/att/authz/cui/CUI.java
new file mode 100644
index 0000000..b5e2b9f
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/cui/CUI.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.cui;
+
+import java.io.PrintWriter;
+import java.security.Principal;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.http.HTransferSS;
+import com.att.cmd.AAFcli;
+import com.att.cssa.rserv.HttpCode;
+
+public class CUI extends HttpCode<AuthzTrans, Void> {
+	private final AuthGUI gui;
+	public CUI(AuthGUI gui) {
+		super(null,"Command Line");
+		this.gui = gui;
+	}
+
+	@Override
+	public void handle(AuthzTrans trans, HttpServletRequest req,HttpServletResponse resp) throws Exception {
+		ServletInputStream isr = req.getInputStream();
+		PrintWriter pw = resp.getWriter();
+		int c;
+		StringBuilder cmd = new StringBuilder();
+
+		while((c=isr.read())>=0) {
+			cmd.append((char)c);
+		}
+
+		Principal p = trans.getUserPrincipal();
+		trans.env().setProperty(Config.AAF_DEFAULT_REALM, trans.env().getProperty(Config.AAF_DEFAULT_REALM,Config.getDefaultRealm()));
+		AAFcli aafcli = new AAFcli(trans.env(), pw, 
+				gui.aafCon.hman(), 
+				gui.aafCon.securityInfo(), new HTransferSS(p,AuthGUI.app, 
+						gui.aafCon.securityInfo()));
+	
+		aafcli.verbose(false);
+		aafcli.gui(true);
+		String cmdStr = cmd.toString();
+		if (!cmdStr.contains("--help")) {
+			cmdStr = cmdStr.replaceAll("help", "--help");
+		}
+		if (!cmdStr.contains("--version")) {
+			cmdStr = cmdStr.replaceAll("version", "--version");
+		}
+		try {
+			aafcli.eval(cmdStr);
+			pw.flush();
+		} catch (Exception e) {
+			pw.flush();
+			pw.println(e.getMessage());
+		} finally {
+			aafcli.close();
+		}
+		
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java b/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java
new file mode 100644
index 0000000..470834e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/AuthGUI.java
@@ -0,0 +1,319 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.cssa.rserv.HttpMethods.GET;
+import static com.att.cssa.rserv.HttpMethods.POST;
+import static com.att.cssa.rserv.HttpMethods.PUT;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Properties;
+
+import com.att.aft.dme2.api.DME2Exception;
+import com.att.aft.dme2.api.DME2Manager;
+import com.att.aft.dme2.api.DME2Server;
+import com.att.aft.dme2.api.DME2ServerProperties;
+import com.att.aft.dme2.api.DME2ServiceHolder;
+import com.att.aft.dme2.api.util.DME2FilterHolder;
+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;
+import com.att.aft.dme2.api.util.DME2ServletHolder;
+import com.att.authz.common.Define;
+import com.att.authz.cui.CUI;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.env.AuthzTransFilter;
+import com.att.authz.env.AuthzTransOnlyFilter;
+import com.att.authz.gui.pages.ApiDocs;
+import com.att.authz.gui.pages.ApiExample;
+import com.att.authz.gui.pages.ApprovalAction;
+import com.att.authz.gui.pages.ApprovalForm;
+import com.att.authz.gui.pages.Home;
+import com.att.authz.gui.pages.LoginLanding;
+import com.att.authz.gui.pages.LoginLandingAction;
+import com.att.authz.gui.pages.NsDetail;
+import com.att.authz.gui.pages.NsHistory;
+import com.att.authz.gui.pages.NsInfoAction;
+import com.att.authz.gui.pages.NsInfoForm;
+import com.att.authz.gui.pages.NssShow;
+import com.att.authz.gui.pages.PassChangeAction;
+import com.att.authz.gui.pages.PassChangeForm;
+import com.att.authz.gui.pages.PendingRequestsShow;
+import com.att.authz.gui.pages.PermDetail;
+import com.att.authz.gui.pages.PermGrantAction;
+import com.att.authz.gui.pages.PermGrantForm;
+import com.att.authz.gui.pages.PermHistory;
+import com.att.authz.gui.pages.PermsShow;
+import com.att.authz.gui.pages.RequestDetail;
+import com.att.authz.gui.pages.RoleDetail;
+import com.att.authz.gui.pages.RoleHistory;
+import com.att.authz.gui.pages.RolesShow;
+import com.att.authz.gui.pages.UserRoleExtend;
+import com.att.authz.gui.pages.UserRoleRemove;
+import com.att.authz.gui.pages.WebCommand;
+import com.att.authz.org.OrganizationFactory;
+import com.att.authz.server.AbsServer;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.config.Config;
+import com.att.cssa.rserv.CachingFileAccess;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.rosetta.env.RosettaDF;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.State;
+
+import aaf.v2_0.Api;
+import aaf.v2_0.Approvals;
+import aaf.v2_0.CredRequest;
+import aaf.v2_0.Error;
+import aaf.v2_0.History;
+import aaf.v2_0.Nss;
+import aaf.v2_0.Perms;
+import aaf.v2_0.RolePermRequest;
+import aaf.v2_0.Roles;
+import aaf.v2_0.UserRoles;
+import aaf.v2_0.Users;
+
+public class AuthGUI extends AbsServer implements State<Env>{
+	public static final int TIMEOUT = 60000;
+	public static final String app = "AAF GUI";
+	
+	public RosettaDF<Perms> permsDF;
+	public RosettaDF<Roles> rolesDF;
+	public RosettaDF<Users> usersDF;
+	public RosettaDF<UserRoles> userrolesDF;
+	public RosettaDF<CredRequest> credReqDF;
+	public RosettaDF<RolePermRequest> rolePermReqDF;
+	public RosettaDF<Approvals> approvalsDF;
+	public RosettaDF<Nss> nssDF;
+	public RosettaDF<Api> apiDF;
+	public RosettaDF<Error> errDF;
+	public RosettaDF<History> historyDF;
+
+	public final AuthzEnv env;
+	public final Slot slot_httpServletRequest;
+
+	public AuthGUI(final AuthzEnv env) throws CadiException, GeneralSecurityException, IOException, APIException {
+		super(env,app);
+		this.env = env;
+		
+		env.setLog4JNames("log4j.properties","authz","gui","audit","init","trace ");
+		OrganizationFactory.setDefaultOrg(env, "com.att.authz.org.att.ATT");
+
+
+		slot_httpServletRequest = env.slot("HTTP_SERVLET_REQUEST");
+		
+		permsDF = env.newDataFactory(Perms.class);
+		rolesDF = env.newDataFactory(Roles.class);
+//			credsDF = env.newDataFactory(Cred.class);
+		usersDF = env.newDataFactory(Users.class);
+		userrolesDF = env.newDataFactory(UserRoles.class);
+		credReqDF = env.newDataFactory(CredRequest.class);
+		rolePermReqDF = env.newDataFactory(RolePermRequest.class);
+		approvalsDF = env.newDataFactory(Approvals.class);
+		nssDF = env.newDataFactory(Nss.class);
+		apiDF = env.newDataFactory(Api.class);
+		errDF   = env.newDataFactory(Error.class);
+		historyDF = env.newDataFactory(History.class);
+
+		/////////////////////////
+		// Screens
+		/////////////////////////
+		// Start Screen
+		final Page start = new Display(this, GET, new Home(this)).page();
+
+		// MyPerms Screens
+		final Page myPerms = new Display(this, GET, new PermsShow(this, start)).page();
+		Page permDetail = new Display(this, GET, new PermDetail(this, start, myPerms)).page();
+							new Display(this, GET, new PermHistory(this,start,myPerms,permDetail));
+
+		// MyRoles Screens
+		final Page myRoles = new Display(this, GET, new RolesShow(this, start)).page();
+		Page roleDetail = new Display(this, GET, new RoleDetail(this, start, myRoles)).page();
+							new Display(this, GET, new RoleHistory(this,start,myRoles,roleDetail));
+							
+		// MyNameSpace
+		final Page myNamespaces = new Display(this, GET, new NssShow(this, start)).page();
+		Page nsDetail = new Display(this, GET, new NsDetail(this, start, myNamespaces)).page();
+			   		  	new Display(this, GET, new NsHistory(this, start,myNamespaces,nsDetail));
+							 
+		// Password Change Screens
+		final Page pwc = new Display(this, GET, new PassChangeForm(this, start)).page();
+						 new Display(this, POST, new PassChangeAction(this, start, pwc));
+
+		// Validation Change Screens
+		final Page validate = new Display(this, GET, new ApprovalForm(this, start)).page();
+							  new Display(this, POST, new ApprovalAction(this, start, validate));
+							
+		// Onboard, Detailed Edit  Screens
+		final Page onb = new Display(this, GET, new NsInfoForm(this, start)).page();
+						 new Display(this, POST, new NsInfoAction(this, start, onb));
+
+		// Web Command Screens
+		/* final Page webCommand =*/ new Display(this, GET, new WebCommand(this, start)).page();
+		
+		// API Docs
+		final Page apidocs = new Display(this, GET, new ApiDocs(this, start)).page();
+							 new Display(this, GET, new ApiExample(this,start, apidocs)).page();
+		
+		// Permission Grant Page
+		final Page permGrant = 	new Display(this, GET, new PermGrantForm(this, start)).page();
+							 	new Display(this, POST, new PermGrantAction(this, start, permGrant)).page();
+							 	
+		// Login Landing if no credentials detected
+		final Page loginLanding = new Display(this, GET, new LoginLanding(this, start)).page();
+								  new Display(this, POST, new LoginLandingAction(this, start, loginLanding));
+								  
+		// User Role Request Extend and Remove
+		new Display(this, GET, new UserRoleExtend(this, start,myRoles)).page();
+		new Display(this, GET, new UserRoleRemove(this, start,myRoles)).page();
+		
+		// See my Pending Requests
+		final Page requestsShow = new Display(this, GET, new PendingRequestsShow(this, start)).page();
+								  new Display(this, GET, new RequestDetail(this, start, requestsShow));
+								  
+		// Command line Mechanism
+		route(env, PUT, "/gui/cui", new CUI(this),"text/plain;charset=utf-8","*/*");
+		
+		///////////////////////  
+		// WebContent Handler
+		///////////////////////
+		route(env,GET,"/theme/:key", new CachingFileAccess<AuthzTrans>(env,
+				CachingFileAccess.CFA_WEB_DIR,"theme"));
+		///////////////////////
+	}
+	
+	public static void main(String[] args) {
+		setup(AuthGUI.class, "authGUI.props");
+	}
+
+	/**
+	 * Start up AuthzAPI as DME2 Service
+	 * @param env
+	 * @param props
+	 * @throws DME2Exception
+	 * @throws CadiException 
+	 */
+	public void startDME2(Properties props) throws DME2Exception, CadiException {
+		
+		DME2Manager dme2 = new DME2Manager("AAF GUI DME2Manager", props);
+        DME2ServiceHolder svcHolder;
+        List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();
+        svcHolder = new DME2ServiceHolder();
+        String serviceName = env.getProperty("DMEServiceName",null);
+    	if(serviceName!=null) {
+	    	svcHolder.setServiceURI(serviceName);
+	        svcHolder.setManager(dme2);
+	        svcHolder.setContext("/");
+	        
+	        
+	        DME2ServletHolder srvHolder = new DME2ServletHolder(this, new String[]{"/gui"});
+	        srvHolder.setContextPath("/*");
+	        slist.add(srvHolder);
+	        
+	        EnumSet<RequestDispatcherType> edlist = EnumSet.of(
+	        		RequestDispatcherType.REQUEST,
+	        		RequestDispatcherType.FORWARD,
+	        		RequestDispatcherType.ASYNC
+	        		);
+
+	        ///////////////////////
+	        // Apply Filters
+	        ///////////////////////
+	        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();
+	        
+	        // Secure all GUI interactions with AuthzTransFilter
+	        flist.add(new DME2FilterHolder(new AuthzTransFilter(env, aafCon, new AAFTrustChecker(
+	        		env.getProperty(Config.CADI_TRUST_PROP, Config.CADI_USER_CHAIN),
+	        		Define.ROOT_NS + ".mechid|"+Define.ROOT_COMPANY+"|trust"
+	        	)),"/gui/*", edlist));
+	        
+	        // Don't need security for display Artifacts or login page
+	        AuthzTransOnlyFilter atof;
+	        flist.add(new DME2FilterHolder(atof =new AuthzTransOnlyFilter(env),"/theme/*", edlist));
+	        flist.add(new DME2FilterHolder(atof,"/js/*", edlist));
+	        flist.add(new DME2FilterHolder(atof,"/login/*", edlist));
+
+	        svcHolder.setFilters(flist);
+	        svcHolder.setServletHolders(slist);
+	        
+	        DME2Server dme2svr = dme2.getServer();
+//	        dme2svr.setGracefulShutdownTimeMs(1000);
+	
+	        env.init().log("Starting AAF GUI with Jetty/DME2 server...");
+	        dme2svr.start();
+	        DME2ServerProperties dsprops = dme2svr.getServerProperties();
+	        try {
+//	        	if(env.getProperty("NO_REGISTER",null)!=null)
+	        	dme2.bindService(svcHolder);
+	        	env.init().log("DME2 is available as HTTP"+(dsprops.isSslEnable()?"/S":""),"on port:",dsprops.getPort());
+
+	            while(true) { // Per DME2 Examples...
+	            	Thread.sleep(5000);
+	            }
+	        } catch(InterruptedException e) {
+	            env.init().log("AAF Jetty Server interrupted!");
+	        } catch(Exception e) { // Error binding service doesn't seem to stop DME2 or Process
+	            env.init().log(e,"DME2 Initialization Error");
+	        	dme2svr.stop();
+	        	System.exit(1);
+	        }
+    	} else {
+    		env.init().log("Properties must contain DMEServiceName");
+    	}
+	}
+
+
+	public AuthzEnv env() {
+		return env;
+	}
+
+	/**
+	 * Derive API Error Class from AAF Response (future)
+	 */
+	public Error getError(AuthzTrans trans, Future<?> fp) {
+//		try {
+			String text = fp.body();
+			Error err = new Error();
+			err.setMessageId(Integer.toString(fp.code()));
+			if(text==null || text.length()==0) {
+				err.setText("**No Message**");
+			} else {
+				err.setText(fp.body());
+			}
+			return err;
+//		} catch (APIException e) {
+//			Error err = new Error();
+//			err.setMessageId(Integer.toString(fp.code()));
+//			err.setText("Could not obtain response from AAF Message: " + e.getMessage());
+//			return err;
+//		}
+	}
+
+	public void writeError(AuthzTrans trans, Future<?> fp, HTMLGen hgen) {
+		Error err = getError(trans,fp);
+
+		String messageBody = err.getText();
+		List<String> vars = err.getVariables();
+		for (int varCounter=0;varCounter<vars.size();) {
+			String var = vars.get(varCounter++);
+			if (messageBody.indexOf("%" + varCounter) >= 0) {
+				messageBody = messageBody.replace("%" + varCounter, var);
+			}
+		}
+
+		String msg = "[" + err.getMessageId() + "] " + messageBody;
+		if(hgen!=null) {
+			hgen.text(msg);
+		}
+		trans.checkpoint("AAF Error: " + msg);
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java b/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java
new file mode 100644
index 0000000..ffcc3f2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/BreadCrumbs.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.LI;
+import static com.att.xgen.html.HTMLGen.UL;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class BreadCrumbs extends NamedCode {
+	private Page[] breadcrumbs;
+
+	public BreadCrumbs(Page ... pages) {
+		super(false,"breadcrumbs");
+		breadcrumbs = pages;
+	}
+	
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		// BreadCrumbs
+		Mark mark = new Mark();
+		hgen.incr(mark, UL);
+		for(Page p : breadcrumbs) {
+			hgen.incr(LI,true)
+				.leaf(A,"href="+p.url()).text(p.name())
+				.end(2);
+		}
+		hgen.end(mark);
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Controls.java b/authz-gui/src/main/java/com/att/authz/gui/Controls.java
new file mode 100644
index 0000000..e87075e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Controls.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+public class Controls extends NamedCode {
+	public Controls() {
+		super(false,"controls");
+	}
+	
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		hgen.incr("form","method=post")
+			.incr("input", true, "type=checkbox", "name=vehicle", "value=Bike").text("I have a bike").end()
+			.text("Password: ")
+			.incr("input", true, "type=password", "id=password1").end()
+			.tagOnly("input", "type=submit", "value=Submit")
+			.end();
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Display.java b/authz-gui/src/main/java/com/att/authz/gui/Display.java
new file mode 100644
index 0000000..a3e6a64
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Display.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.util.Enumeration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.cssa.rserv.HttpCode;
+import com.att.cssa.rserv.HttpMethods;
+import org.onap.aaf.inno.env.Slot;
+
+public class Display {
+	private final Page get;
+	public Display(final AuthGUI gui, final HttpMethods meth, final Page page) {
+		get = page;
+		final String[] fields = page.fields();
+		final Slot slots[] = new Slot[fields.length];
+		String prefix = page.name() + '.';
+		for(int i=0;i<slots.length;++i) {
+			slots[i] = gui.env.slot(prefix + fields[i]);
+		}
+
+		/*
+		 * We handle all the "Form POST" calls here with a naming convention that allows us to create arrays from strings.
+		 * 
+		 * On the HTTP side, elements concatenate their name with their Index number (if multiple).  In this code, 
+		 * we turn such names into arrays with same index number.  Then, we place them in the Transaction "Properties" so that 
+		 * it can be transferred to subclasses easily.
+		 */ 
+		if(meth.equals(HttpMethods.POST)) {
+			// Here, we'll expect FORM URL Encoded Data, which we need to get from the body
+			gui.route(gui.env, meth, page.url(), 
+				new HttpCode<AuthzTrans,AuthGUI>(gui,page.name()) {
+					@Override
+					public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+						trans.put(gui.slot_httpServletRequest, req);
+						for(int i=0; i<fields.length;++i) {
+							int idx = fields[i].indexOf("[]");
+							if(idx<0) { // single value
+								trans.put(slots[i], req.getParameter(fields[i])); // assume first value
+							} else { // multi value
+								String field=fields[i].substring(0, idx);
+								String[] array = new String[30];
+								for(Enumeration<String> names = req.getParameterNames(); names.hasMoreElements();) {
+									String key = names.nextElement();
+									if(key.subSequence(0, idx).equals(field)) {
+										try {
+											int x = Integer.parseInt(key.substring(field.length()));
+											if(x>=array.length) {
+												String[] temp = new String[x+10];
+												System.arraycopy(temp, 0, temp, 0, array.length);
+												array = temp;
+											}
+											array[x]=req.getParameter(key);
+										} catch (NumberFormatException e) {
+											trans.debug().log(e);
+										}
+									}
+								}
+								trans.put(slots[i], array);
+							}
+						}
+						page.replay(context,trans,resp.getOutputStream(),"general");
+					}
+				}, "application/x-www-form-urlencoded","*/*");
+
+		} else {
+			// Transfer whether Page shouldn't be cached to local Final var.
+			final boolean no_cache = page.no_cache;
+			
+			gui.route(gui.env, meth, page.url(), 
+				new HttpCode<AuthzTrans,AuthGUI>(gui,page.name()) {
+					@Override
+					public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {
+						trans.put(gui.slot_httpServletRequest, req);
+						for(int i=0; i<slots.length;++i) {
+							int idx = fields[i].indexOf("[]");
+							if(idx<0) { // single value
+								trans.put(slots[i], req.getParameter(fields[i]));
+							} else { // multi value
+								String[] array = new String[30];
+								String field=fields[i].substring(0, idx);
+								
+								for(Enumeration<String> mm = req.getParameterNames();mm.hasMoreElements();) {
+									String key = mm.nextElement();
+									if(key.startsWith(field)) {
+										try {
+											int x = Integer.parseInt(key.substring(field.length()));
+											if(x>=array.length) {
+												String[] temp = new String[x+10];
+												System.arraycopy(temp, 0, temp, 0, array.length);
+												array = temp;
+											}
+											array[x]=req.getParameter(key);
+										} catch (NumberFormatException e) {
+											trans.debug().log(e);
+										}
+									}
+								}
+								trans.put(slots[i], array);
+							}
+						}
+						page.replay(context,trans,resp.getOutputStream(),"general");
+					}
+					
+					@Override
+					public boolean no_cache() {
+						return no_cache;
+					}
+				}, "text/html","*/*");
+		}
+
+	}
+	
+	public Page page() { 
+		return get;
+	}
+}
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Form.java b/authz-gui/src/main/java/com/att/authz/gui/Form.java
new file mode 100644
index 0000000..52f5699
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Form.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import java.io.IOException;
+
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+public class Form extends NamedCode {
+	private String preamble;
+	private NamedCode content;
+	
+	public Form(boolean no_cache, NamedCode content) {
+		super(no_cache,content.idattrs());
+		this.content = content;
+		preamble=null;
+		idattrs = content.idattrs();
+	}
+	
+	public Form preamble(String preamble) {
+		this.preamble = preamble;
+		return this;
+	}
+	
+
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		if(preamble!=null) {
+			hgen.incr("p","class=preamble").text(preamble).end();
+		}
+		hgen.incr("form","method=post");
+	
+		content.code(cache, hgen);
+		
+		hgen.tagOnly("input", "type=submit", "value=Submit")
+			.tagOnly("input", "type=reset", "value=Reset")
+		.end();
+	}
+
+	/* (non-Javadoc)
+	 * @see com.att.authz.gui.NamedCode#idattrs()
+	 */
+	@Override
+	public String[] idattrs() {
+		return content.idattrs();
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java b/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java
new file mode 100644
index 0000000..90e1170
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/NamedCode.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import com.att.xgen.Code;
+import com.att.xgen.html.HTMLGen;
+
+
+
+public abstract class NamedCode implements Code<HTMLGen> {
+	public final boolean no_cache;
+	protected String[] idattrs;
+	
+	/*
+	 *  Mark whether this code should not be cached, and any attributes 
+	 */
+	public NamedCode(final boolean no_cache, String ... idattrs) {
+		this.idattrs = idattrs;
+		this.no_cache = no_cache;
+	}
+	
+	/**
+	 * Return ID and Any Attributes needed to create a "div" section of this code
+	 * @return
+	 */
+	public String[] idattrs() {
+		return idattrs;
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Page.java b/authz-gui/src/main/java/com/att/authz/gui/Page.java
new file mode 100644
index 0000000..a8c48e6
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Page.java
@@ -0,0 +1,292 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.H1;
+import static com.att.xgen.html.HTMLGen.LI;
+import static com.att.xgen.html.HTMLGen.TITLE;
+import static com.att.xgen.html.HTMLGen.UL;
+
+import java.io.IOException;
+import java.security.Principal;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.util.Split;
+import com.att.xgen.Cache;
+import com.att.xgen.CacheGen;
+import com.att.xgen.Code;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLCacheGen;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.Imports;
+
+/**
+ * A Base "Mobile First" Page 
+ * 
+ *
+ */
+public class Page extends HTMLCacheGen {
+	public static enum BROWSER {iPhone,html5,ie,ieOld};
+	
+	public static final int MAX_LINE=20;
+
+	protected static final String[] NO_FIELDS = new String[0];
+
+	private static final String ENV_CONTEXT = "envContext";
+	private static final String DME_SERVICE_NAME = "DMEServiceName";
+	private static final String ROUTE_OFFER = "routeOffer";
+	private static final String BROWSER_TYPE = "BROWSER_TYPE";
+
+	private final String bcName, bcUrl;
+	private final String[] fields;
+
+	public final boolean no_cache;
+
+	public String name() {
+		return bcName;
+	}
+	
+	public String url() {
+		return bcUrl;
+	}
+	
+	public String[] fields() {
+		return fields;
+	}
+	
+	public Page(AuthzEnv env, String name, String url, String [] fields, final NamedCode ... content) throws APIException,IOException {
+		this(env,name,url,1,fields,content);
+	}
+	
+	public Page(AuthzEnv env, String name, String url, int backdots, String [] fields, final NamedCode ... content) throws APIException,IOException {
+		super(CacheGen.PRETTY, new PageCode(env, backdots, content));
+		bcName = name;
+		bcUrl = url;
+		this.fields = fields;
+		// Mark which fields must be "no_cache"
+		boolean no_cacheTemp=false;
+		for(NamedCode nc : content) {
+			if(nc.no_cache) { 
+				no_cacheTemp=true;
+				break;
+			}
+		}
+		no_cache=no_cacheTemp;
+	}
+	
+	private static class PageCode implements Code<HTMLGen> {
+			private final NamedCode[] content;
+			private final Slot browserSlot;
+			private final int backdots;
+			protected AuthzEnv env;
+
+			public PageCode(AuthzEnv env, int backdots, final NamedCode[] content) {
+				this.content = content;
+				this.backdots = backdots;
+				browserSlot = env.slot(BROWSER_TYPE);
+				this.env = env;
+			}
+			
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				// Note: I found that App Storage saves everything about the page, or not.  Thus, if you declare the page uncacheable, none of the 
+				// Artifacts, like JPGs are stored, which makes this feature useless for Server driven elements
+				//hgen.html("manifest=../theme/aaf.appcache");
+				cache.dynamic(hgen,  new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+					@Override
+					public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+						switch(browser(trans,browserSlot)) {
+							case ieOld:
+							case ie:
+								hgen.directive("!DOCTYPE html");
+								hgen.directive("meta", "http-equiv=X-UA-Compatible","content=IE=11");
+							default:
+						}
+					}
+				});
+				hgen.html();
+				Mark head = hgen.head();
+					hgen.leaf(TITLE).text("AT&amp;T Authentication/Authorization Tool").end();
+					hgen.imports(new Imports(backdots).css("theme/aaf5.css")
+								 			   	.js("theme/comm.js")
+												.js("theme/console.js")
+												.js("theme/common.js"));
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+						@Override
+						public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							switch(browser(trans,browserSlot)) {
+								case iPhone:
+									hgen.imports(new Imports(backdots).css("theme/aaf5iPhone.css"));
+									break;
+								case ie:
+								case ieOld:
+									hgen.js().text("document.createElement('header');")
+											.text("document.createElement('nav');")
+											.done();
+								case html5:
+									hgen.imports(new Imports(backdots).css("theme/aaf5Desktop.css"));
+									break;
+							}
+						}
+					});
+					hgen.end(head);
+					
+				Mark body = hgen.body();
+					Mark header = hgen.header();
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+						@Override
+						public void code(AuthGUI state, AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen xgen)
+								throws APIException, IOException {
+							// Obtain Server Info, and print
+							String DMEServiceName = trans.getProperty(DME_SERVICE_NAME);
+							String env = DMEServiceName.substring(
+									DMEServiceName.indexOf(ENV_CONTEXT),
+									DMEServiceName.indexOf(ROUTE_OFFER) -1).split("=")[1];
+							
+							xgen.leaf(H1).text("AT&amp;T Auth Tool on " + env).end();
+							xgen.leaf("p","id=version").text("AAF Version: " + trans.getProperty(Config.AAF_DEPLOYED_VERSION, "N/A")).end();
+							
+							// Obtain User Info, and print
+							Principal p = trans.getUserPrincipal();
+							String user;
+							if(p==null) {
+								user = "please choose a Login Authority";
+							} else {
+								user = p.getName();
+							}
+							xgen.leaf("p","id=welcome").text("Welcome, " + user).end();
+							
+							switch(browser(trans,browserSlot)) {
+								case ieOld:
+								case ie:
+									xgen.incr("h5").text("This app is Mobile First HTML5.  Internet Explorer " 
+											+ " does not support all HTML5 standards. Old, non TSS-Standard versions may not function correctly.").br()
+											.text("  For best results, use a highly compliant HTML5 browser like Firefox.")
+										.end();
+									break;
+								default:
+							}
+						}
+					});
+					
+					hgen.hr();
+					
+					int cIdx;
+					NamedCode nc;
+					// If BreadCrumbs, put here
+					if(content.length>0 && content[0] instanceof BreadCrumbs) {
+						nc = content[0];
+						Mark ctnt = hgen.divID(nc.idattrs());
+						nc.code(cache, hgen);
+						hgen.end(ctnt);
+						cIdx = 1;
+					} else {
+						cIdx = 0;
+					}
+					
+					hgen.end(header);
+					
+					Mark inner = hgen.divID("inner");
+						// Content
+						for(int i=cIdx;i<content.length;++i) {
+							nc = content[i];
+							Mark ctnt = hgen.divID(nc.idattrs());
+							nc.code(cache, hgen);
+							hgen.end(ctnt);
+						}
+
+					hgen.end(inner);	
+					
+					// Navigation - Using older Nav to work with decrepit  IE versions
+					
+					Mark nav = hgen.divID("nav");
+					hgen.incr("h2").text("Related Links").end();
+					hgen.incr(UL)
+						 .leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.aaf_help")).text("AAF WIKI").end(2)
+						 .leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.cadi_help")).text("CADI WIKI").end(2);
+						String tools = env.getProperty("aaf_tools");
+						if(tools!=null) {
+							hgen.hr()
+								.incr(HTMLGen.UL,"style=margin-left:5%")
+							 	.leaf(HTMLGen.H3).text("Related Tools").end();
+
+							for(String tool : Split.splitTrim(',',tools)) {
+								hgen.leaf(LI).leaf(A,"href="+env.getProperty("aaf_url.tool."+tool)).text(tool.toUpperCase() + " Help").end(2);
+							}
+							hgen.end();
+						}
+						 hgen.end();
+					
+					hgen.hr();
+					
+					hgen.end(nav);
+					// Footer - Using older Footer to work with decrepit IE versions
+					Mark footer = hgen.divID("footer");
+						hgen.textCR(1, "(c) 2014-6 AT&amp;T Inc. All Rights Reserved")
+						.end(footer);
+						
+					hgen.end(body);
+				hgen.endAll();
+		}
+	}
+
+	public static String getBrowserType() {
+		return BROWSER_TYPE;
+	}
+	
+	/**
+	 * It's IE if int >=0
+	 * 
+	 * Use int found in "ieVersion"
+	 * 
+	 * Official IE 7
+	 * 		Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 1.1.4322; 
+	 * 		.NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
+	 * Official IE 8
+	 * 		Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; 
+	 * 		.NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; ATT)
+	 * 
+	 * IE 11 Compatibility
+	 * 		Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; SLCC2; .NET CLR 2.0.50727; 
+	 * 		.NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
+	 * 
+	 * IE 11 (not Compatiblity)
+	 * 		Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; 
+	 * 		.NET CLR 3.5.30729; .NET CLR 3.0.30729;	Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3; HVD; ATT)
+	 * 
+	 * @param trans
+	 * @return
+	 */
+	public static BROWSER browser(AuthzTrans trans, Slot slot) {
+		BROWSER br = trans.get(slot, null);
+		if(br==null) {
+			String agent = trans.agent();
+			int msie; 
+			if(agent.contains("iPhone") /* other phones? */) {
+				br=BROWSER.iPhone;
+			} else if ((msie = agent.indexOf("MSIE"))>=0) {
+				msie+=5;
+				int end = agent.indexOf(";",msie);
+				float ver;
+				try {
+					ver = Float.valueOf(agent.substring(msie,end));
+					br = ver<8f?BROWSER.ieOld:BROWSER.ie;
+				} catch (Exception e) {
+					br = BROWSER.ie;
+				}
+			} else {
+				br = BROWSER.html5;
+			}
+			trans.put(slot,br);
+		}
+		return br;
+	}
+}
+
diff --git a/authz-gui/src/main/java/com/att/authz/gui/Table.java b/authz-gui/src/main/java/com/att/authz/gui/Table.java
new file mode 100644
index 0000000..f15d4be
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/Table.java
@@ -0,0 +1,149 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+import static com.att.xgen.html.HTMLGen.TD;
+import static com.att.xgen.html.HTMLGen.TR;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import com.att.authz.gui.table.AbsCell;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.Trans;
+import org.onap.aaf.inno.env.TransStore;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+import com.att.xgen.html.State;
+
+public class Table<S extends State<Env>, TRANS extends TransStore> extends NamedCode {
+	private final Slot ROW_MSG_SLOT, EMPTY_TABLE_SLOT;
+	private final String title;
+	private final String[] columns;
+	private final Rows rows;
+	
+	public Table(String title, TRANS trans, Data<S,TRANS> data, String ... attrs)  {
+		super(true,attrs);
+		ROW_MSG_SLOT=trans.slot("TABLE_ROW_MSG");
+		EMPTY_TABLE_SLOT=trans.slot("TABLE_EMPTY");
+		this.columns = data.headers();
+		boolean alt = false;
+		for(String s : attrs) {
+			if("class=std".equals(s) || "class=stdform".equals(s)) {
+				alt=true;
+			}
+		}
+		rows = new Rows(data,alt?1:0);
+		this.title = title;
+		
+		// Derive an ID from title (from no spaces, etc), and prepend to IDAttributes (Protected from NamedCode)
+		idattrs = new String[attrs.length+1];
+		idattrs[0] = title.replaceAll("\\s","");
+		System.arraycopy(attrs, 0, idattrs, 1, attrs.length);
+	}
+
+	@Override
+	public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+		Mark table = new Mark();
+		Mark tr = new Mark();
+		hgen.incr(table,TABLE)
+				.leaf("caption", "class=title").text(title).end()
+				.incr(tr,TR);
+					for(String column : columns) {
+						hgen.leaf("th").text(column).end();
+					}
+				hgen.end(tr);
+				
+		// Load Rows Dynamically
+		cache.dynamic(hgen, rows);
+		// End Table
+		hgen.end(table); 
+			
+		// Print Message from Row Gathering, if available
+		cache.dynamic(hgen, new DynamicCode<HTMLGen,S,TRANS>() {
+			@Override
+			public void code(S state, TRANS trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				String msg;
+				if((msg = trans.get(EMPTY_TABLE_SLOT, null))!=null) {
+					hgen.incr("style").text("#inner tr,caption,input,p.preamble {display: none;}#inner p.notfound {margin: 0px 0px 0px 20px}").end();
+					hgen.incr(HTMLGen.P,"class=notfound").text(msg).end().br();
+				} else if((msg=trans.get(ROW_MSG_SLOT,null))!=null) { 
+					hgen.p(msg).br();
+				}
+			}
+		});
+	}
+
+	public static class Cells {
+		public static final Cells EMPTY = new Cells();
+		private Cells() {
+			cells = new AbsCell[0][0];
+			msg = "No Data Found";
+		}
+		
+		public Cells(ArrayList<AbsCell[]> arrayCells, String msg) {
+			cells = new AbsCell[arrayCells.size()][];
+			arrayCells.toArray(cells);
+			this.msg = msg;
+		}
+		public AbsCell[][] cells;
+		public String msg;
+	}
+	
+	public interface Data<S extends State<Env>, TRANS extends Trans> {
+		public Cells get(S state,TRANS trans);
+		public String[] headers();
+	}
+
+	private class Rows extends DynamicCode<HTMLGen,S,TRANS> {
+		private Data<S,TRANS> data;
+		private int alt;
+		
+		public Rows(Data<S,TRANS> data, int alt) {
+			this.data = data;
+			this.alt = alt;
+		}
+		
+		@Override
+		public void code(S state, TRANS trans, Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+			Mark tr = new Mark();
+			Mark td = new Mark();
+			
+			int alt = this.alt;
+			Cells cells = data.get(state, trans);
+			if(cells.cells.length>0) {
+				for(AbsCell[] row : cells.cells) {
+					switch(alt) {
+						case 1:
+							alt=2;
+						case 0:
+							hgen.incr(tr,TR);
+							break;
+						default:
+							alt=1;
+							hgen.incr(tr,TR,"class=alt");
+					}
+					for(AbsCell cell :row) {
+						hgen.leaf(td, TD,cell.attrs());
+						cell.write(hgen);
+						hgen.end(td);
+					}
+					hgen.end(tr);
+				}
+				// Pass Msg back to Table code, in order to place after Table Complete
+				if(cells.msg!=null) {
+					trans.put(ROW_MSG_SLOT,cells.msg);
+				}
+
+			} else {
+				trans.put(EMPTY_TABLE_SLOT,cells.msg);
+			}
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java
new file mode 100644
index 0000000..75ab331
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiDocs.java
@@ -0,0 +1,304 @@
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import com.att.cssa.rserv.HttpMethods;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Api;
+import aaf.v2_0.Api.Route;
+
+public class ApiDocs extends Page {
+	// Package on purpose
+	private static final String HREF = "/gui/api";
+	private static final String NAME = "AAF RESTful API";
+	private static final String fields[] = {};
+	private static final String ERROR_LINK = "<a href=\"./example/"
+			+ "YXBwbGljYXRpb24vRXJyb3IranNvbg=="
+//			+ Symm.base64noSplit().encode("application/Error+json") 
+			+ "\">JSON</a> "
+			+ "<a href=\"./example/"
+			+ "YXBwbGljYXRpb24vRXJyb3IreG1s"
+//			+ Symm.base64noSplit().encode("application/Error+xml") 
+			+ "\">XML</a> ";
+
+	
+	public ApiDocs(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new Preamble(),
+			new Table<AuthGUI,AuthzTrans>("AAF API Reference",gui.env.newTransNoAvg(),new Model(), "class=std")
+			);
+	}
+	
+	private static class Preamble extends NamedCode {
+
+		private static final String I = "i";
+
+		public Preamble() {
+			super(false, "preamble");
+		}
+
+		@Override
+		public void code(Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+			xgen.leaf(HTMLGen.H1).text("AAF 2.0 RESTful interface").end()
+				.hr();
+			xgen.leaf(HTMLGen.H2).text("Accessing RESTful").end();
+			xgen.incr(HTMLGen.UL)
+					.leaf(HTMLGen.LI).text("AAF RESTful service is secured by the following:").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("The Client must utilize HTTP/S. Non Secure HTTP is not acceptable").end()
+						.leaf(HTMLGen.LI).text("The Client MUST supply an Identity validated by one of the following mechanisms").end()
+						.incr(HTMLGen.UL)
+							.leaf(HTMLGen.LI).text("(Near Future) Application level Certificate").end()
+						.end()
+					.end()
+					.leaf(HTMLGen.LI).text("Responses").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("Each API Entity listed shows what structure will be accepted by service (ContentType) "
+								+ "or responded with by service (Accept). Therefore, use these in making your call. Critical for PUT/POST.").end()
+						.leaf(HTMLGen.LI).text("Each API call may respond with JSON or XML.  Choose the ContentType/Accept that has "
+								+ "+json after the type for JSON or +xml after the Type for XML").end()
+						.leaf(HTMLGen.LI).text("XSDs for Versions").end()
+						.incr(HTMLGen.UL)
+							.leaf(HTMLGen.LI).leaf(HTMLGen.A,"href=../theme/aaf_2_0.xsd").text("API 2.0").end().end()
+						.end()
+						.leaf(HTMLGen.LI).text("AAF can support multiple Versions of the API.  Choose the ContentType/Accept that has "
+								+ "the appropriate version=?.?").end()
+						.leaf(HTMLGen.LI).text("All Errors coming from AAF return AT&T Standard Error Message as a String: " + ERROR_LINK 
+								+ " (does not apply to errors from Container)").end()
+					.end()
+					.leaf(HTMLGen.LI).text("Character Restrictions").end()
+					.incr(HTMLGen.UL)
+						.leaf(HTMLGen.LI).text("Character Restrictions must depend on the Enforcement Point used").end()
+						.leaf(HTMLGen.LI).text("Most AAF usage will be AAF Enforcement Point Characters for Instance and Action are:")
+							.br().br().leaf(I).text("a-zA-Z0-9,.()_-=%").end()
+							.br().br().text("For Instance, you may declare a multi-dimensional key with : (colon) separator, example:").end()
+							.br().leaf(I).text(":myCluster:myKeyspace").end()
+							.br().br().text("The * (asterix) may be used as a wild-card by itself or within the multi-dimensional key, example:")
+							.br().leaf(I).text(":myCluster:*").end()
+							.br().br().text("The % (percent) character can be used as an Escape Character. Applications can use % followed by 2 hexadecimal "
+									+ "digits to cover odd keys.  It is their code, however, which must translate.")
+							.br().br().text("The = (equals) is allowed so that Applications can pass Base64 encodations of binary keys").end()
+						.leaf(HTMLGen.LI).text("Ask for a Consultation on how these are typically used, or, if your tool is the only Enforcement Point, if set may be expanded").end()
+					.end()
+				.end();
+			/*
+			
+			The Content is defined in the AAF XSD - TODO Add aaf.xsdâ€ï¿½;
+			Character Restrictions
+
+			URLs impose restrictions on characters which have specific meanings. This means you cannot have these characters in the Field Content you send
+			“#â€ï¿½ is a “Fragment URLâ€ï¿½, or anchor. Content after this Character is not sent. AAF cannot do anything about this… don’t use it.
+			“?=&â€ï¿½. These are used to delineate Parameters.
+			“/“ is used to separate fields
+			*/
+		}
+		
+	};
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		public static final String[] HEADERS = new String[] {"Entity","Method","Path Info","Description"};
+		private static final TextCell BLANK = new TextCell("");
+	
+		@Override
+		public String[] headers() {
+			return HEADERS;
+		}
+		
+		@SuppressWarnings("unchecked")
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> ns = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> perms = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> roles = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> user = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> aafOnly = new ArrayList<AbsCell[]>();
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			
+	
+			TimeTaken tt = trans.start("AAF APIs",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Api> fa = client.read("/api",gui.apiDF);
+						if(fa.get(5000)) {
+							tt.done();
+							TimeTaken tt2 = trans.start("Load Data", Env.SUB);
+							try {
+								if(fa.value!=null)for(Route r : fa.value.getRoute()) {
+									String path = r.getPath();
+									// Build info
+									StringBuilder desc = new StringBuilder();
+			
+									desc.append("<p class=double>");
+									desc.append(r.getDesc());
+									
+									if(r.getComments().size()>0) {
+										for(String ct : r.getComments()) {
+											desc.append("</p><p class=api_comment>");
+											desc.append(ct);
+										}
+									}
+			
+									if(r.getParam().size()>0) {
+										desc.append("<hr><p class=api_label>Parameters</p>");
+										
+										for(String params : r.getParam()) {
+											String param[] = params.split("\\s*\\|\\s*");
+											desc.append("</p><p class=api_contentType>");
+											desc.append(param[0]);
+											desc.append(" : ");
+											desc.append(param[1]);
+											if("true".equalsIgnoreCase(param[2])) {
+												desc.append(" (Required)");
+											}
+										}
+									}
+			
+			
+									if(r.getExpected()!=0) {
+										desc.append("</p><p class=api_label>Expected HTTP Code</p><p class=api_comment>");
+										desc.append(r.getExpected());
+									} 
+			
+									if(r.getExplicitErr().size()!=0) {
+										desc.append("</p><p class=api_label>Explicit HTTP Error Codes</p><p class=api_comment>");
+										boolean first = true;
+										for(int ee : r.getExplicitErr()) {
+											if(first) {
+												first = false;
+											} else {
+												desc.append(", ");
+											}
+											desc.append(ee);
+										}
+									}
+			
+									desc.append("</p><p class=api_label>");
+									desc.append("GET".equals(r.getMeth())?"Accept:":"ContentType:");
+									Collections.sort(r.getContentType());
+									if(r.getPath().startsWith("/authn/basicAuth")) {
+										desc.append("</p><p class=api_contentType>text/plain");
+									}
+									for(String ct : r.getContentType()) {
+										if(ct.contains("version=2")) {
+											desc.append("</p><p class=api_contentType><a href=\"./example/");
+											try {
+												desc.append(Symm.base64noSplit.encode(ct));
+											} catch (IOException e) {
+												throw new CadiException(e);
+											}
+											desc.append("\"/>");
+											desc.append(ct);
+											desc.append("</a>");
+										}
+									}
+									desc.append("</p>");
+									
+									
+									AbsCell[] sa = new AbsCell[] {
+										null,
+										new TextCell(r.getMeth(),"class=right"),
+										new TextCell(r.getPath()),
+										new TextCell(desc.toString()),
+									};
+			
+									if(path.startsWith("/authz/perm")) {
+										sa[0] = perms.size()==0?new TextCell("PERMISSION"):BLANK;
+										perms.add(sa);
+									} else if(path.startsWith("/authz/role") || path.startsWith("/authz/userRole")) {
+										sa[0] = roles.size()==0?new TextCell("ROLE"):BLANK;
+										roles.add(sa);
+									} else if(path.startsWith("/authz/ns")) {
+										sa[0] = ns.size()==0?new TextCell("NAMESPACE"):BLANK;
+										ns.add(sa);
+									} else if(path.startsWith("/authn/basicAuth") 
+										|| path.startsWith("/authn/validate")
+										|| path.startsWith("/authz/user")) {
+										sa[0] = user.size()==0?new TextCell("USER"):BLANK;
+										user.add(sa);
+									} else {
+										sa[0] = aafOnly.size()==0?new TextCell("AAF ONLY"):BLANK;
+										aafOnly.add(sa);
+									}
+								}
+								//TODO if(trans.fish(p))
+								prepare(rv, perms,roles,ns,user);
+							} finally {
+								tt2.done();
+							}
+						} else {
+							gui.writeError(trans, fa, null);
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e.getMessage());
+			} finally {
+				tt.done();
+			}
+			
+			return new Cells(rv,null);
+		}
+
+		@SuppressWarnings("unchecked")
+		private void prepare(ArrayList<AbsCell[]> rv, ArrayList<AbsCell[]> ... all) {
+			AbsCell lead;
+			AbsCell[] row;
+			for(ArrayList<AbsCell[]> al : all) {
+				if(al.size()>1) {
+					row = al.get(0);
+					lead = row[0];
+					row[0]=BLANK;
+					al.get(0).clone()[0]=BLANK;
+					Collections.sort(al, new Comparator<AbsCell[]>() {
+						@Override
+						public int compare(AbsCell[] ca1, AbsCell[] ca2) {
+							int meth = ((TextCell)ca1[2]).name.compareTo(
+									   ((TextCell)ca2[2]).name);
+							if(meth == 0) {
+								return (HttpMethods.valueOf(((TextCell)ca1[1]).name).compareTo(
+										HttpMethods.valueOf(((TextCell)ca2[1]).name)));
+							} else { 
+								return meth;
+							}
+						}
+					});
+					// set new first row
+					al.get(0)[0]=lead;
+
+					rv.addAll(al);
+				}
+			}
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java
new file mode 100644
index 0000000..5e8f81c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApiExample.java
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Data.TYPE;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Error;
+
+/**
+ * Detail Page for Permissions
+ * 
+ *
+ */
+public class ApiExample extends Page {
+	public static final String HREF = "/gui/example/:tc";
+	public static final String NAME = "APIExample";
+
+	public ApiExample(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, 2/*backdots*/, new String[] {"API Code Example"},
+				new BreadCrumbs(breadcrumbs),
+				new Model()
+				);
+	}
+	
+	private static class Model extends NamedCode {
+		private static final String WITH_OPTIONAL_PARAMETERS = "\n\n////////////\n  Data with Optional Parameters \n////////////\n\n";
+
+		public Model() {
+			super(false);
+		}
+
+		@Override
+		public void code(Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+			Mark inner = xgen.divID("inner");
+			xgen.divID("example","class=std");
+			cache.dynamic(xgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+				@Override
+				public void code(final AuthGUI gui, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+					TimeTaken tt = trans.start("Code Example",Env.REMOTE);
+					try {
+						final String typecode;
+						int prefix = trans.path().lastIndexOf('/')+1;
+						String encoded = trans.path().substring(prefix);
+						typecode = Symm.base64noSplit.decode(encoded);
+						Future<String> fp = gui.client().read("/api/example/" + encoded,
+								"application/Void+json"
+								);
+						Future<String> fs2;
+						if(typecode.contains("Request+")) {
+							fs2 = gui.client().read("/api/example/" + typecode+"?optional=true",
+									"application/Void+json"
+									);
+						} else {
+							fs2=null;
+						}
+						
+						
+						if(fp.get(5000)) {
+								xgen.incr(HTMLGen.H1).text("Sample Code").end()
+								.incr(HTMLGen.H5).text(typecode).end();
+								xgen.incr("pre");
+								if(typecode.contains("+xml")) {
+									xgen.xml(fp.body());
+									if(fs2!=null && fs2.get(5000)) {
+										xgen.text(WITH_OPTIONAL_PARAMETERS);
+										xgen.xml(fs2.body());
+									}
+								} else {
+									xgen.text(fp.body());
+									if(fs2!=null && fs2.get(5000)) {
+										xgen.text(WITH_OPTIONAL_PARAMETERS);
+										xgen.text(fs2.body());
+									}
+								}
+								xgen.end();
+						} else {
+							Error err = gui.errDF.newData().in(TYPE.JSON).load(fp.body()).asObject();
+							xgen.incr(HTMLGen.H3)
+								.textCR(2,"Error from AAF Service")
+								.end();
+							
+							xgen.p("Error Code: ",err.getMessageId())
+								.p(err.getText())
+								.end();
+								
+						}
+
+					} catch (APIException e) {
+						throw e;
+					} catch (IOException e) {
+						throw e;
+					} catch (Exception e) {
+						throw new APIException(e);
+					}finally {
+						tt.done();
+					}
+				}
+					
+			});
+			xgen.end(inner);
+		}
+	}
+
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java
new file mode 100644
index 0000000..22230cc
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalAction.java
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class ApprovalAction extends Page {
+	public ApprovalAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Approvals",ApprovalForm.HREF, ApprovalForm.FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sAppr = gui.env.slot(ApprovalForm.NAME+'.'+ApprovalForm.FIELDS[0]);
+				final Slot sUser = gui.env.slot(ApprovalForm.NAME+'.'+ApprovalForm.FIELDS[1]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {				
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							boolean fail = true;
+							String[] appr = trans.get(sAppr,null);
+							String user = trans.get(sUser,null);
+							String lastPage = ApprovalForm.HREF;
+							if (user != null) {
+								lastPage += "?user="+user;
+							}
+							
+							if(appr==null) {
+								hgen.p("No Approvals have been selected.");
+							} else {
+								Approval app;
+								final Approvals apps = new Approvals();
+								int count = 0;
+								for(String a : appr) {
+									if(a!=null) {
+										int idx = a.indexOf('|');
+										if(idx>=0) {
+											app = new Approval();
+											app.setStatus(a.substring(0,idx));
+											app.setTicket(a.substring(++idx));
+											app.setApprover(trans.getUserPrincipal().getName());
+											apps.getApprovals().add(app);
+											++count;
+										}
+									}
+								}
+								if(apps.getApprovals().isEmpty()) {
+									hgen.p("No Approvals have been sent.");
+								} else {
+									TimeTaken tt = trans.start("AAF Update Approvals",Env.REMOTE);
+									try {
+										final int total = count;
+										fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+											@Override
+											public Boolean code(Rcli<?> client) throws APIException, CadiException  {
+												boolean fail2 = true;
+												Future<Approvals> fa = client.update("/authz/approval",gui.approvalsDF,apps);
+												if(fa.get(AuthGUI.TIMEOUT)) {
+													// Do Remote Call
+													fail2 = false;
+													hgen.p(total + (total==1?" Approval has":" Approvals have") + " been Saved");
+												} else {
+													gui.writeError(trans, fa, hgen);
+												}
+												return fail2;
+											}
+										});
+									} catch (Exception e) {
+										e.printStackTrace();
+									} finally {
+										tt.done();
+									}
+								}
+
+							hgen.br();
+							if(fail) {
+								hgen.incr("a",true,"href="+lastPage).text("Try again").end();
+							} else {
+								hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+							}
+							}
+						}
+					});
+				}
+			});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java
new file mode 100644
index 0000000..e6cf041
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/ApprovalForm.java
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Form;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.ButtonCell;
+import com.att.authz.gui.table.RadioCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextAndRefCell;
+import com.att.authz.gui.table.TextCell;
+import com.att.authz.org.Organization;
+import com.att.authz.org.Organization.Identity;
+import com.att.authz.org.OrganizationFactory;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+
+public class ApprovalForm extends Page {
+	// Package on purpose
+	static final String NAME="Approvals";
+	static final String HREF = "/gui/approve";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static final String[] FIELDS = new String[] {"line[]","user"};
+	
+	
+	public ApprovalForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(false, "filterByUser") {
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String user = trans.get(trans.env().slot(NAME+".user"),"");
+							hgen.incr("p", "class=userFilter")
+								.text("Filter by User:")
+								.tagOnly("input", "type=text", "value="+user, "id=userTextBox")
+								.tagOnly("input", "type=button", "onclick=userFilter('"+HREF+"');", "value=Go!")
+								.end();
+								}
+					});
+				}
+			},
+			new Form(true,new Table<AuthGUI,AuthzTrans>("Approval Requests", gui.env.newTransNoAvg(),new Model(gui.env()),"class=stdform"))
+				.preamble("The following requires your Approval to proceed in the AAF System.</p><p class=subtext>Hover on Identity for Name; click for WebPhone"),
+			new NamedCode(false, "selectAlljs") {
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					Mark jsStart = new Mark();
+					hgen.js(jsStart);
+					hgen.text("function selectAll(radioClass) {");
+					hgen.text("var radios = document.querySelectorAll(\".\"+radioClass);");
+					hgen.text("for (i = 0; i < radios.length; i++) {");
+					hgen.text("radios[i].checked = true;");
+					hgen.text("}");
+					hgen.text("}");
+					hgen.end(jsStart);
+				}
+			});
+		
+	}
+	
+	/**
+	 * Implement the Table Content for Approvals
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Identity","Request","Approve","Deny"};
+		private static final Object THE_DOMAIN = null;
+		private Slot sUser;
+		
+		public Model(AuthzEnv env) {
+			sUser = env.slot(NAME+".user");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String userParam = trans.get(sUser, null);
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			TimeTaken tt = trans.start("AAF Get Approvals for Approver",Env.REMOTE);
+			try {
+				final List<Approval> pendingApprovals = new ArrayList<Approval>();
+				final List<Integer> beginIndicesPerApprover = new ArrayList<Integer>();
+				int numLeft = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Integer>() {
+					@Override
+					public Integer code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<aaf.v2_0.Approvals> fa = client.read("/authz/approval/approver/"+trans.user(),gui.approvalsDF);
+						int numLeft = 0;
+						if(fa.get(AuthGUI.TIMEOUT)) {
+							
+							if(fa.value!=null) {
+								for (Approval appr : fa.value.getApprovals()) {
+									if (appr.getStatus().equals("pending")) {
+										if (userParam!=null) {
+											if (!appr.getUser().equalsIgnoreCase(userParam)) {
+												numLeft++;
+												continue;
+											}
+										}
+										pendingApprovals.add(appr);
+									}
+								}
+							}
+							
+							String prevApprover = null;
+							int overallIndex = 0;
+								
+							for (Approval appr : pendingApprovals) {
+								String currApprover = appr.getApprover();
+								if (!currApprover.equals(prevApprover)) {
+									prevApprover = currApprover;
+									beginIndicesPerApprover.add(overallIndex);
+								}
+								overallIndex++;
+							}
+						}
+						return numLeft;
+					}
+				});
+				
+				if (pendingApprovals.size() > 0) {
+					// Only add select all links if we have approvals
+					AbsCell[] selectAllRow = new AbsCell[] {
+							AbsCell.Null,
+							AbsCell.Null,
+							new ButtonCell("all", "onclick=selectAll('approve')", "class=selectAllButton"),
+							new ButtonCell("all", "onclick=selectAll('deny')", "class=selectAllButton")
+						};
+					rv.add(selectAllRow);
+				}
+						
+				int line=-1;
+				
+				while (beginIndicesPerApprover.size() > 0) {
+					int beginIndex = beginIndicesPerApprover.remove(0);
+					int endIndex = (beginIndicesPerApprover.isEmpty()?pendingApprovals.size():beginIndicesPerApprover.get(0));
+					List<Approval> currApproverList = pendingApprovals.subList(beginIndex, endIndex);
+					
+					String currApproverFull = currApproverList.get(0).getApprover();
+					String currApproverShort = currApproverFull.substring(0,currApproverFull.indexOf('@'));
+					String currApprover = (trans.user().indexOf('@')<0?currApproverShort:currApproverFull);
+					if (!currApprover.equals(trans.user())) {
+						AbsCell[] approverHeader;
+						if (currApproverFull.substring(currApproverFull.indexOf('@')).equals(THE_DOMAIN)) {
+							approverHeader = new AbsCell[] { 
+									new TextAndRefCell("Approvals Delegated to Me by ", currApprover,
+											WEBPHONE + currApproverShort, 
+											new String[] {"colspan=4", "class=head"})
+							};
+						} else {
+							approverHeader = new AbsCell[] { 
+									new TextCell("Approvals Delegated to Me by " + currApprover,
+											new String[] {"colspan=4", "class=head"})
+							};
+						}
+						rv.add(approverHeader);
+					}
+					
+					// Sort by User Requesting
+					Collections.sort(currApproverList, new Comparator<Approval>() {
+						@Override
+						public int compare(Approval a1, Approval a2) {
+							return a1.getUser().compareTo(a2.getUser());
+						}
+					});
+					
+					String prevUser = null;
+					for (Approval appr : currApproverList) {
+						if(++line<MAX_LINE) { // limit number displayed at one time.
+							AbsCell userCell;
+							String user = appr.getUser();
+							if(user.equals(prevUser)) {
+								userCell = AbsCell.Null; 
+							} else {
+								String title;
+								Organization org = OrganizationFactory.obtain(trans.env(), user);
+								if(org==null) {
+									title="";
+								} else {
+									Identity au = org.getIdentity(trans, user);
+									if(au!=null) {
+										if(au.type().equals("MECHID")) {
+											title="title=Sponsor is " + au.responsibleTo();
+										} else {
+											title="title=" + au.fullName();
+										}
+									} else {
+										title="";
+									}
+								}
+								userCell = new RefCell(prevUser=user, 
+									"" //TODO add Organization Link ability
+									,title);
+							}
+							AbsCell[] sa = new AbsCell[] {
+								userCell,
+								new TextCell(appr.getMemo()),
+								new RadioCell("line"+ line,"approve", "approved|"+appr.getTicket()),
+								new RadioCell("line"+ line,"deny", "denied|"+appr.getTicket())
+							};
+							rv.add(sa);
+						} else {
+							++numLeft;
+						}
+					}
+				}
+				if(numLeft>0) {
+					msg = "After these, there will be " + numLeft + " approvals left to process";
+				}
+				if(rv.size()==0) {
+					if (numLeft>0) {
+						msg = "No Approvals to process at this time for user " + userParam +". You have " 
+							+ numLeft + " other approvals to process.";
+					} else {
+						msg = "No Approvals to process at this time";
+					}
+				}
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+		return new Cells(rv,msg);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
new file mode 100644
index 0000000..3c6abd0
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/Home.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.H3;
+
+import java.io.IOException;
+
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+
+public class Home extends Page {
+	public static final String HREF = "/gui/home";
+	public Home(final AuthGUI gui) throws APIException, IOException {
+		super(gui.env,"Home",HREF, NO_FIELDS, new NamedCode(false,"content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen xgen) throws APIException, IOException {
+//				// TEMP
+//				JSGen jsg = xgen.js();
+//				jsg.function("httpPost","sURL","sParam")
+//					.text("var oURL = new java.net.URL(sURL)")
+//					.text("var oConn = oURL.openConnection();")
+//					.text("oConn.setDoInput(true);")
+//					.text("oConn.setDoOutpu(true);")
+//					.text("oConn.setUseCaches(false);")
+//					.text("oConn.setRequestProperty(\"Content-Type\",\"application/x-www-form-urlencoded\");")
+//					.text(text)
+//				jsg.done();
+				// TEMP
+				final Mark pages = xgen.divID("Pages");
+				xgen.leaf(H3).text("Choose from the following:").end()
+					.leaf(A,"href=myperms").text("My Permissions").end()
+					.leaf(A,"href=myroles").text("My Roles").end()
+				//	TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page
+					.leaf(A,"href=mynamespaces").text("My Namespaces").end()
+					.leaf(A,"href=approve").text("My Approvals").end()
+					.leaf(A, "href=myrequests").text("My Pending Requests").end()
+					// Enable later
+//					.leaf(A, "href=onboard").text("Onboarding").end()
+				// Password Change.  If logged in as CSP/GSO, go to their page
+					.leaf(A,"href=passwd").text("Password Management").end()
+					.leaf(A,"href=cui").text("Command Prompt").end()
+					.leaf(A,"href=api").text("AAF API").end()
+					;
+				
+				xgen.end(pages);
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
new file mode 100644
index 0000000..6ca1608
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLanding.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.URLDecoder;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLanding extends Page {
+	public static final String HREF = "/login";
+	static final String NAME = "Login";
+	static final String fields[] = {"id","password","environment"};
+	static final String envs[] = {"DEV","TEST","PROD"};
+	
+	public LoginLanding(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME,HREF, fields, new NamedCode(true, "content") {
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				hgen.leaf("p").text("No login credentials are found in your current session. " +
+					     "Choose your preferred login option to continue.").end();
+				
+				Mark loginPaths = hgen.divID("Pages");
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI authGUI, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen) throws APIException, IOException {
+						HttpServletRequest req = trans.get(gui.slot_httpServletRequest, null);
+						if(req!=null) {
+							String query = req.getQueryString();
+							if(query!=null) {
+								for(String qs : query.split("&")) {
+									int equals = qs.indexOf('=');
+									xgen.leaf(HTMLGen.A, "href="+URLDecoder.decode(qs.substring(equals+1),Config.UTF_8)).text(qs.substring(0,equals).replace('_', ' ')).end();
+								}
+							}
+						}
+						xgen.leaf(HTMLGen.A, "href=gui/home?Authentication=BasicAuth").text("AAF Basic Auth").end();
+					}
+				});
+//				hgen.leaf("a", "href=#","onclick=divVisibility('cso');").text("Global Login").end()
+//					.incr("p", "id=cso","style=display:none").text("this will redirect to global login").end()
+//					.leaf("a", "href=#","onclick=divVisibility('tguard');").text("tGuard").end()
+//					.incr("p", "id=tguard","style=display:none").text("this will redirect to tGuard login").end()
+//				hgen.leaf("a", "href=#","onclick=divVisibility('basicauth');").text("AAF Basic Auth").end();
+				hgen.end(loginPaths);
+				
+//					hgen.incr("form","method=post","style=display:none","id=basicauth","gui/home?Authentication=BasicAuth");
+//					Mark table = new Mark(TABLE);
+//					hgen.incr(table);
+//					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+//						@Override
+//						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	
+//								throws APIException, IOException {
+//							hgen
+//							.input(fields[0],"Username",true)
+//							.input(fields[1],"Password",true, "type=password");
+//						Mark selectRow = new Mark();
+//						hgen
+//						.incr(selectRow, "tr")
+//						.incr("td")
+//						.incr("label", "for=envs", "required").text("Environment").end()
+//						.end()
+//						.incr("td")
+//						.incr("select", "name=envs", "id=envs", "required")
+//						.incr("option", "value=").text("Select Environment").end();
+//						for (String env : envs) {
+//							hgen.incr("option", "value="+env).text(env).end();
+//						}
+//						hgen			
+//						.end(selectRow) 
+							
+//						hgen.end();
+//						}
+//					});
+//					hgen.end();
+//					hgen.tagOnly("input", "type=submit", "value=Submit")
+//						.tagOnly("input", "type=reset", "value=Reset")
+//					.end();
+			
+
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
new file mode 100644
index 0000000..d70aca4
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/LoginLandingAction.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class LoginLandingAction extends Page {
+	public LoginLandingAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Login",LoginLanding.HREF, LoginLanding.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[0]);
+//				final Slot sPassword = gui.env.slot(LoginLanding.NAME+'.'+LoginLanding.fields[1]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String username = trans.get(sID,null);
+//							String password = trans.get(sPassword,null);
+
+							hgen.p("User: "+username);
+							hgen.p("Pass: ********");
+							
+							// TODO: clarification from JG
+							// put in request header?
+							// then pass through authn/basicAuth call?
+							
+						}
+					});
+				}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
new file mode 100644
index 0000000..75ff137
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsDetail.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import com.att.cmd.AAFcli;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+import aaf.v2_0.Users;
+import aaf.v2_0.Users.User;
+
+public class NsDetail extends Page {
+	
+	public static final String HREF = "/gui/nsdetail";
+	public static final String NAME = "NsDetail";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	public static enum NS_FIELD { OWNERS, ADMINS, ROLES, PERMISSIONS, CREDS};
+	private static final String BLANK = "";
+
+	public NsDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"name"}, 
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Namespace Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Namespace Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];		
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private Slot name;
+		public Model(AuthzEnv env) {
+			name = env.slot(NAME+".name");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String nsName = trans.get(name, null);
+			if(nsName==null) {
+				return Cells.EMPTY;
+			}
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			rv.add(new AbsCell[]{new TextCell("Name:"),new TextCell(nsName)});
+
+			final TimeTaken tt = trans.start("AAF Namespace Details",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(),new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Nss> fn = client.read("/authz/nss/"+nsName,gui.nssDF);
+
+						if(fn.get(AuthGUI.TIMEOUT)) {
+							tt.done();
+							try {
+//								TimeTaken tt = trans.start("Load Data", Env.SUB);
+								
+								for(Ns n : fn.value.getNs()) {
+									String desc = (n.getDescription()!=null?n.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									
+									addField(trans, rv, n.getAdmin(), NS_FIELD.ADMINS);
+									addField(trans, rv, n.getResponsible(), NS_FIELD.OWNERS);
+			
+									Future<Users> fu = client.read(
+													"/authn/creds/ns/"+nsName, 
+													gui.usersDF
+													);
+									List<String> creds = new ArrayList<String>();
+									if(fu.get(AAFcli.timeout())) {
+										for (User u : fu.value.getUser()) {
+											StringBuilder sb = new StringBuilder(u.getId());
+											switch(u.getType()) {
+												case 1: sb.append(" (U/Pass) "); break;
+												case 10: sb.append(" (Cert) "); break;
+												case 200: sb.append(" (x509) "); break;
+												default:
+													sb.append(" ");
+											}
+											sb.append(Chrono.niceDateStamp(u.getExpires()));
+											creds.add(sb.toString());
+										}
+									}
+									addField(trans, rv, creds, NS_FIELD.CREDS);
+			
+									Future<Roles> fr = client.read(
+													"/authz/roles/ns/"+nsName, 
+													gui.rolesDF
+													);
+									List<String> roles = new ArrayList<String>();
+									if(fr.get(AAFcli.timeout())) {
+										for (Role r : fr.value.getRole()) {
+											roles.add(r.getName());
+										}
+									}
+									addField(trans, rv, roles, NS_FIELD.ROLES);
+									
+									
+									Future<Perms> fp = client.read(
+													"/authz/perms/ns/"+nsName, 
+													gui.permsDF
+													);
+									List<String> perms = new ArrayList<String>();
+			
+									if(fp.get(AAFcli.timeout())) {
+										for (Perm p : fp.value.getPerm()) {
+											perms.add(p.getType() + "|" + p.getInstance() + "|" + p.getAction());
+										}
+									}
+									addField(trans, rv, perms, NS_FIELD.PERMISSIONS);
+								}
+								String historyLink = NsHistory.HREF 
+										+ "?name=" + nsName;
+								rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+							} finally {
+								tt.done();
+							}
+						} else {
+							rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				tt.done();
+			}
+			return new Cells(rv,null);
+		}
+
+		private void addField(AuthzTrans trans, ArrayList<AbsCell[]> rv, List<String> values, NS_FIELD field) {
+			if (!values.isEmpty()) {
+				switch(field) {
+				case OWNERS:
+				case ADMINS:
+				case CREDS:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						String user = values.get(i);
+						AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+								new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+						rv.add(new AbsCell[] {
+								label, 
+								userCell
+						});
+					}
+					break;
+				case ROLES:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						rv.add(new AbsCell[] {
+								label, 
+								new TextCell(values.get(i))
+						});
+					}
+					break;
+				case PERMISSIONS:
+					for (int i=0; i< values.size(); i++) {
+						AbsCell label = (i==0?new TextCell(sentenceCase(field)+":"):AbsCell.Null);
+						String perm = values.get(i);
+						String[] fields = perm.split("\\|");
+						String grantLink = PermGrantForm.HREF 
+								+ "?type=" + fields[0].trim()
+								+ "&amp;instance=" + fields[1].trim()
+								+ "&amp;action=" + fields[2].trim();
+						
+						rv.add(new AbsCell[] {
+								label, 
+								new TextCell(perm),
+								new RefCell("Grant This Perm", grantLink)
+						});
+					}
+					break;
+				}
+
+			}
+		}
+
+		private String sentenceCase(NS_FIELD field) {
+			String sField = field.toString();
+			return sField.substring(0, 1).toUpperCase() + sField.substring(1).toLowerCase();
+		}
+	
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
new file mode 100644
index 0000000..653b9e7
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsHistory.java
@@ -0,0 +1,210 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+public class NsHistory extends Page {
+	static final String NAME="NsHistory";
+	static final String HREF = "/gui/nsHistory";
+	static final String FIELDS[] = {"name","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+							AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public NsHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot name = gui.env.slot(NAME+".name");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String obName = trans.get(name, null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Namespace [ " + obName + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = NsDetail.HREF + "?name=" + obName;
+							hgen.js()
+								.text("alterLink('nsdetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a","href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?name=" + obName+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+								
+						}
+					});
+				}
+			}
+
+			);
+	}
+
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+		
+
+	
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot name;
+		private Slot dates;
+		
+		public Model(AuthzEnv env) {
+			name = env.slot(NAME+".name");
+			dates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(name,null);
+			final String oDates = trans.get(dates,null);
+			
+			if(oName==null) {
+				return Cells.EMPTY;
+			}
+			
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			final TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						if (oDates != null) {
+							client.setQueryParams("yyyymm="+oDates);
+						}
+						Future<History> fh = client.read("/authz/hist/ns/"+oName,gui.historyDF);
+						if (fh.get(AuthGUI.TIMEOUT)) {
+							tt.done();
+							TimeTaken tt2 = trans.start("Load History Data", Env.SUB);
+							try {
+								List<Item> histItems = fh.value.getItem();
+								
+								java.util.Collections.sort(histItems, new Comparator<Item>() {
+									@Override
+									public int compare(Item o1, Item o2) {
+										return o2.getTimestamp().compare(o1.getTimestamp());
+									}
+								});
+								
+								for (Item i : histItems) {
+									String user = i.getUser();
+									AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+											new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+									
+									rv.add(new AbsCell[] {
+											new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+											userCell,
+											new TextCell(i.getMemo())
+									});
+								}
+							} finally {
+								tt2.done();
+							}
+						} else {
+							if (fh.code()==403) {
+								rv.add(new AbsCell[] {new TextCell("You may not view History of Namespace [" + oName + "]", "colspan = 3", "class=center")});
+							} else {
+								rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+							}
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+		return new Cells(rv,msg);
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
new file mode 100644
index 0000000..19a90c3
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoAction.java
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class NsInfoAction extends Page {
+	public NsInfoAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"Onboard",PassChangeForm.HREF, PassChangeForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+				final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+				final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+				final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+				final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String id = trans.get(sID,null);
+							String currPass = trans.get(sCurrPass,null);
+							String password = trans.get(sPassword,null);
+							String password2 = trans.get(sPassword2,null);
+							
+							// Run Validations
+							boolean fail = true;
+							
+							if (id==null || id.indexOf('@')<=0) {
+								hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+							} else if(password == null || password2 == null || currPass == null) {
+								hgen.p("Data Entry Failure: Both Password Fields need entries.");
+							} else if(!password.equals(password2)) {
+								hgen.p("Data Entry Failure: Passwords do not match.");
+							} else { // everything else is checked by Server
+								final CredRequest cred = new CredRequest();
+								cred.setId(id);
+								cred.setPassword(currPass);
+								try {
+									fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+										@Override
+										public Boolean code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+											TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+											try {
+												Future<CredRequest> fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+															"/authn/validate",
+															gui.credReqDF,
+															cred
+														);
+												boolean go;
+												boolean fail = true;
+												fcr.get(5000);
+												if(fcr.code() == 200) {
+													hgen.p("Current Password validated");
+													go = true;
+												} else {
+													hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+													go = false;
+												}
+												if(go) {
+													tt.done();
+													tt = trans.start("AAF Change Password",Env.REMOTE);
+													try {
+														// Change over Cred to reset mode
+														cred.setPassword(password);
+														String start = trans.get(startDate, null);
+														if(start!=null) {
+															try {
+																cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+															} catch (ParseException e) {
+																throw new CadiException(e);
+															}
+														}
+														
+														fcr = client.create(
+																"/authn/cred",
+																gui.credReqDF,
+																cred
+																);
+					
+														if(fcr.get(5000)) {
+															// Do Remote Call
+															hgen.p("New Password has been added.");
+															fail = false;
+														} else {
+															gui.writeError(trans, fcr, hgen);
+														}
+													} finally {
+														tt.done();
+													}
+												}
+ 												return fail;
+											} finally {
+												tt.done();
+											}
+										}
+									});
+
+								} catch (Exception e) {
+									hgen.p("Unknown Error");
+									e.printStackTrace();
+								}
+							}
+						hgen.br();
+						if(fail) {
+							hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+						} else {
+							hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+						}
+					}
+				});
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
new file mode 100644
index 0000000..5cb8ff2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NsInfoForm.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.A;
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+import aaf.v2_0.Nss.Ns.Attrib;
+
+public class NsInfoForm extends Page {
+	// Package on purpose
+	static final String HREF = "/gui/onboard";
+	static final String NAME = "Onboarding";
+	static final String fields[] = {"ns","description","mots","owners","admins"};
+	
+	public NsInfoForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+
+			private final Slot sID = gui.env.slot(NsInfoForm.NAME+'.'+NsInfoForm.fields[0]);
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf(HTMLGen.H2).text("Namespace Info").end()
+				     .leaf("p").text("Hover over Fields for Tool Tips, or click ")
+				     	.leaf(A,"href="+gui.env.getProperty("aaf_url.gui_onboard","")).text("Here").end()
+				     	.text(" for more information")
+				     .end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@SuppressWarnings("unchecked")
+					@Override
+					public void code(final AuthGUI gui, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						final String incomingID= trans.get(sID, "");
+						final String[] info = new String[fields.length];
+						final Object own_adm[] = new Object[2]; 
+						for(int i=0;i<info.length;++i) {
+							info[i]="";
+						}
+						if(incomingID.length()>0) {
+							TimeTaken tt = trans.start("AAF Namespace Info",Env.REMOTE);
+							try {
+								gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+									@Override
+									public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+										Future<Nss> fn = client.read("/authz/nss/"+incomingID,gui.nssDF);
+										if(fn.get(AuthGUI.TIMEOUT)) {
+											for(Ns ns : fn.value.getNs()) {
+												info[0]=ns.getName();
+												info[1]=ns.getDescription();
+												for(Attrib attr: ns.getAttrib()) {
+													switch(attr.getKey()) {
+														case "mots":
+															info[2]=attr.getValue();
+														default:
+													}
+												}
+												own_adm[0]=ns.getResponsible();
+												own_adm[1]=ns.getAdmin();
+											}
+										} else {
+											trans.error().log(fn.body());
+										}
+										return null;
+									}
+								});
+							} catch (Exception e) {
+								trans.error().log("Unable to access AAF for NS Info",incomingID);
+								e.printStackTrace();
+							} finally {
+								tt.done();
+							}
+						}
+						hgen.input(fields[0],"Namespace",false,"value="+info[0],"title=AAF Namespace")
+							.input(fields[1],"Description*",true,"value="+info[1],"title=Full Application Name, Tool Name or Group")
+							.input(fields[2],"MOTS ID",false,"value="+info[2],"title=MOTS ID if this is an Application, and has MOTS");
+						Mark endTD = new Mark(),endTR=new Mark();
+						// Owners
+						hgen.incr(endTR,HTMLGen.TR)
+								.incr(endTD,HTMLGen.TD)
+									.leaf("label","for="+fields[3]).text("Responsible Party")
+								.end(endTD)
+								.incr(endTD,HTMLGen.TD)
+									.tagOnly("input","id="+fields[3],"title=Owner of App, must be an Non-Bargained Employee");
+									if(own_adm[0]!=null) {
+										for(String s : (List<String>)own_adm[0]) {
+											hgen.incr("label",true).text(s).end();
+										}
+									}
+							hgen.end(endTR);
+
+							// Admins
+							hgen.incr(endTR,HTMLGen.TR)
+								.incr(endTD,HTMLGen.TD)
+									.leaf("label","for="+fields[4]).text("Administrators")
+								.end(endTD)
+								.incr(endTD,HTMLGen.TD)
+									.tagOnly("input","id="+fields[4],"title=Admins may be employees, contractors or mechIDs");
+									if(own_adm[1]!=null) {
+										for(String s : (List<String>)own_adm[1]) {
+											hgen.incr(HTMLGen.P,true).text(s).end();
+										}
+									}
+								hgen.end(endTR)
+						.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+					.end();
+
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
new file mode 100644
index 0000000..3ca12d9
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/NssShow.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Nss;
+import aaf.v2_0.Nss.Ns;
+
+public class NssShow extends Page {
+	public static final String HREF = "/gui/mynamespaces";
+
+	public NssShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyNamespaces",HREF, NO_FIELDS,
+				new BreadCrumbs(breadcrumbs), 
+				new Table<AuthGUI,AuthzTrans>("Namespaces I administer",gui.env.newTransNoAvg(),new Model("admin",gui.env), 
+						"class=std", "style=display: inline-block; width: 45%; margin: 10px;"),
+				new Table<AuthGUI,AuthzTrans>("Namespaces I own",gui.env.newTransNoAvg(),new Model("responsible",gui.env),
+						"class=std", "style=display: inline-block; width: 45%; margin: 10px;"));
+	}
+	
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private String[] headers;
+		private String privilege = null;
+		public final Slot sNssByUser;
+		private boolean isAdmin;
+
+		public Model(String privilege,AuthzEnv env) {
+			super();
+			headers = new String[] {privilege};
+			this.privilege = privilege;
+			isAdmin = "admin".equals(privilege);
+			sNssByUser = env.slot("NSS_SHOW_MODEL_DATA");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			List<Ns> nss = trans.get(sNssByUser, null);
+			if(nss==null) {
+				TimeTaken tt = trans.start("AAF Nss by User for " + privilege,Env.REMOTE);
+				try {
+					nss = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<List<Ns>>() {
+						@Override
+						public List<Ns> code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							List<Ns> nss = null;
+							Future<Nss> fp = client.read("/authz/nss/either/" + trans.user(),gui.nssDF);
+							if(fp.get(AuthGUI.TIMEOUT)) {
+								TimeTaken tt = trans.start("Load Data for " + privilege, Env.SUB);
+								try {
+									if(fp.value!=null) {
+										nss = fp.value.getNs();
+										Collections.sort(nss, new Comparator<Ns>() {
+											public int compare(Ns ns1, Ns ns2) {
+												return ns1.getName().compareToIgnoreCase(ns2.getName());
+											}
+										});
+										trans.put(sNssByUser,nss);
+									} 
+								} finally {
+									tt.done();
+								}
+							}else {
+								gui.writeError(trans, fp, null);
+							}
+							return nss;
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				} finally {
+					tt.done();
+				}
+			}
+			
+			if(nss!=null) {
+				for(Ns n : nss) {
+					if((isAdmin && !n.getAdmin().isEmpty())
+					  || (!isAdmin && !n.getResponsible().isEmpty())) {
+						AbsCell[] sa = new AbsCell[] {
+							new RefCell(n.getName(),NsDetail.HREF
+									+"?name="+n.getName()),
+						};
+						rv.add(sa);
+					}
+				}
+			}
+
+			return new Cells(rv,null);
+		}
+	}
+	
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
new file mode 100644
index 0000000..1c57515
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeAction.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.ParseException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import org.onap.aaf.inno.env.util.Chrono;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.CredRequest;
+
+public class PassChangeAction extends Page {
+	public PassChangeAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,"PassChange",PassChangeForm.HREF, PassChangeForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+				final Slot sCurrPass = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[1]);
+				final Slot sPassword = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[2]);
+				final Slot sPassword2 = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[3]);
+				final Slot startDate = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[4]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+							String id = trans.get(sID,null);
+							String currPass = trans.get(sCurrPass,null);
+							String password = trans.get(sPassword,null);
+							String password2 = trans.get(sPassword2,null);
+							
+							// Run Validations
+							boolean fail = true;
+							
+							if (id==null || id.indexOf('@')<=0) {
+								hgen.p("Data Entry Failure: Please enter a valid ID, including domain.");
+							} else if(password == null || password2 == null || currPass == null) {
+								hgen.p("Data Entry Failure: Both Password Fields need entries.");
+							} else if(!password.equals(password2)) {
+								hgen.p("Data Entry Failure: Passwords do not match.");
+							} else { // everything else is checked by Server
+								final CredRequest cred = new CredRequest();
+								cred.setId(id);
+								cred.setPassword(currPass);
+								try {
+									fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+										@Override
+										public Boolean code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+											boolean fail = true;
+											boolean go = false;
+											TimeTaken tt = trans.start("Check Current Password",Env.REMOTE);
+											try {
+												Future<CredRequest> fcr = client.create( // Note: Need "Post", because of hiding password in SSL Data
+															"/authn/validate",gui.credReqDF,cred);
+												
+												fcr.get(5000);
+												if(fcr.code() == 200) {
+													hgen.p("Current Password validated");
+													go = true;
+												} else {
+													hgen.p(String.format("Invalid Current Password: %d %s",fcr.code(),fcr.body()));
+													go = false;
+												}
+											} finally {
+												tt.done();
+											}
+											if(go) {
+												tt = trans.start("AAF Change Password",Env.REMOTE);
+												try {
+													// Change over Cred to reset mode
+													cred.setPassword(password);
+													String start = trans.get(startDate, null);
+													if(start!=null) {
+														try {
+															cred.setStart(Chrono.timeStamp(Chrono.dateOnlyFmt.parse(start)));
+														} catch (ParseException e) {
+															throw new CadiException(e);
+														}
+													}
+													
+													Future<CredRequest> fcr = client.create(
+															"/authn/cred",
+															gui.credReqDF,
+															cred
+															);
+		
+													if(fcr.get(5000)) {
+														// Do Remote Call
+														hgen.p("New Password has been added.");
+														fail = false;
+													} else {
+														gui.writeError(trans, fcr, hgen);
+													}
+												} finally {
+													tt.done();
+												}
+											} 
+											return fail;
+										}
+										
+									});
+							} catch (Exception e) {
+								hgen.p("Unknown Error");
+								e.printStackTrace();
+							}
+								
+						}
+						hgen.br();
+						if(fail) {
+							hgen.incr("a",true,"href="+PassChangeForm.HREF+"?id="+id).text("Try again").end();
+						} else {
+							hgen.incr("a",true,"href="+Home.HREF).text("Home").end(); 
+						}
+					}
+				});
+			}
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
new file mode 100644
index 0000000..440c0db
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PassChangeForm.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Slot;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class PassChangeForm extends Page {
+	// Package on purpose
+	static final String HREF = "/gui/passwd";
+	static final String NAME = "PassChange";
+	static final String fields[] = {"id","current","password","password2","startDate"};
+	
+	public PassChangeForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+			private final Slot sID = gui.env.slot(PassChangeForm.NAME+'.'+PassChangeForm.fields[0]);
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf("p").text("You are requesting a new Mechanical Password in the AAF System.  " +
+				     "So that you can perform clean migrations, you will be able to use both this " +
+				     "new password and the old one until their respective expiration dates.").end()
+				     .leaf("p").text("Note: You must be a Namespace Admin where the MechID resides.").end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+//						GregorianCalendar gc = new GregorianCalendar();
+//						System.out.println(gc.toString());
+						String incomingID= trans.get(sID, "");
+						hgen
+						.input(fields[0],"ID*",true,"value="+incomingID)
+						.input(fields[1],"Current Password*",true,"type=password")
+						.input(fields[2],"New Password*",true, "type=password")
+						.input(fields[3], "Reenter New Password*",true, "type=password")
+//						.input(fields[3],"Start Date",false,"type=date", "value="+
+//								Chrono.dateOnlyFmt.format(new Date(System.currentTimeMillis()))
+//								)
+						.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+				.end();
+
+			}
+		});
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
new file mode 100644
index 0000000..8bdb329
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PendingRequestsShow.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class PendingRequestsShow extends Page {
+	public static final String HREF = "/gui/myrequests";
+	public static final String NAME = "MyRequests";
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+	
+	public PendingRequestsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME,HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new NamedCode(true,"expedite") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						hgen
+							.leaf("p", "class=expedite_request").text("These are your submitted Requests that are awaiting Approval. ")
+							.br()
+							.text("To Expedite a Request: ")
+							.leaf("a","href=#expedite_directions","onclick=divVisibility('expedite_directions');")
+								.text("Click Here").end()
+							.divID("expedite_directions", "style=display:none");
+						hgen
+							.incr(HTMLGen.OL)
+							.incr(HTMLGen.LI)
+							.leaf("a","href="+ApprovalForm.HREF+"?user="+trans.user(), "id=userApprove")
+							.text("Copy This Link")
+							.end()
+							.end()
+							.incr(HTMLGen.LI)
+							.text("Send it to the Approver Listed")
+							.end()
+							.end()
+							.text("NOTE: Using this link, the Approver will only see your requests. You only need to send this link once!")
+							.end()
+							.end();
+					}
+				});
+			}
+		},
+			new Table<AuthGUI,AuthzTrans>("Pending Requests",gui.env.newTransNoAvg(),new Model(), "class=std")
+		);
+					
+
+	}
+
+	/**
+	 * Implement the Table Content for Requests by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+		private static final String[] headers = new String[] {"Request Date","Status","Memo","Approver"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Get Approvals by User",Env.REMOTE);
+						try {
+							Future<Approvals> fa = client.read("/authz/approval/user/"+trans.user(),gui.approvalsDF);
+							if(fa.get(5000)) {
+								tt.done();
+								tt = trans.start("Load Data", Env.SUB);
+								if(fa.value!=null) {
+									List<Approval> approvals = fa.value.getApprovals();
+									Collections.sort(approvals, new Comparator<Approval>() {
+										@Override
+										public int compare(Approval a1, Approval a2) {
+											UUID id1 = UUID.fromString(a1.getId());
+											UUID id2 = UUID.fromString(a2.getId());
+											return id1.timestamp()<=id2.timestamp()?1:-1;
+										}
+									});
+									
+									String prevTicket = null;
+									for(Approval a : approvals) {
+										String approver = a.getApprover();
+										String approverShort = approver.substring(0,approver.indexOf('@'));
+										
+										AbsCell tsCell = null;
+										String ticket = a.getTicket();
+										if (ticket.equals(prevTicket)) {
+											tsCell = AbsCell.Null;
+										} else {
+											UUID id = UUID.fromString(a.getId());
+											tsCell = new RefCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),
+													RequestDetail.HREF + "?ticket=" + a.getTicket());
+											prevTicket = ticket;
+										}
+										
+										AbsCell approverCell = null;
+										if (approver.endsWith(CSP_ATT_COM)) {
+											approverCell = new RefCell(approver, WEBPHONE + approverShort);
+										} else {
+											approverCell = new TextCell(approver);
+										}
+										AbsCell[] sa = new AbsCell[] {
+											tsCell,
+											new TextCell(a.getStatus()),
+											new TextCell(a.getMemo()),
+											approverCell
+										};
+										rv.add(sa);
+									}
+								}
+							} else {
+								gui.writeError(trans, fa, null);
+							}
+						} finally {
+							tt.done();
+						}
+
+
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+			return new Cells(rv,null);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
new file mode 100644
index 0000000..ad26674
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermDetail.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.aft.dme2.internal.jetty.http.HttpStatus;
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Detail Page for Permissions
+ *
+ */
+public class PermDetail extends Page {
+	public static final String HREF = "/gui/permdetail";
+	public static final String NAME = "PermDetail";
+	private static final String BLANK = "";
+
+	public PermDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"type","instance","action"},
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Permission Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Permissions Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];
+		private Slot type, instance, action;
+		public Model(AuthzEnv env) {
+			type = env.slot(NAME+".type");
+			instance = env.slot(NAME+".instance");
+			action = env.slot(NAME+".action");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String pType = trans.get(type, null);
+			final String pInstance = trans.get(instance, null);
+			final String pAction = trans.get(action, null);
+			if(pType==null || pInstance==null || pAction==null) {
+				return Cells.EMPTY;
+			}
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			rv.add(new AbsCell[]{new TextCell("Type:"),new TextCell(pType)});
+			rv.add(new AbsCell[]{new TextCell("Instance:"),new TextCell(pInstance)});
+			rv.add(new AbsCell[]{new TextCell("Action:"),new TextCell(pAction)});
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Perm Details",Env.REMOTE);
+						try {
+							Future<Perms> fp= client.read("/authz/perms/"+pType + '/' + pInstance + '/' + pAction,gui.permsDF);
+					
+							if(fp.get(AuthGUI.TIMEOUT)) {
+								tt.done();
+								tt = trans.start("Load Data", Env.SUB);
+								List<Perm> ps = fp.value.getPerm();
+								if(!ps.isEmpty()) {
+									Perm perm = fp.value.getPerm().get(0);
+									String desc = (perm.getDescription()!=null?perm.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									boolean first=true;
+									for(String r : perm.getRoles()) {
+										if(first){
+											first=false;
+											rv.add(new AbsCell[] {
+													new TextCell("Associated Roles:"),
+													new TextCell(r)
+												});
+										} else {
+											rv.add(new AbsCell[] {
+												AbsCell.Null,
+												new TextCell(r)
+											});
+										}
+									}
+								}
+								String historyLink = PermHistory.HREF 
+										+ "?type=" + pType + "&instance=" + pInstance + "&action=" + pAction;
+								
+								rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+							} else {
+								rv.add(new AbsCell[] {new TextCell(
+									fp.code()==HttpStatus.NOT_FOUND_404?
+										"*** Implicit Permission ***":
+										"*** Data Unavailable ***"
+										)});
+							}
+						} finally {
+							tt.done();
+						}
+
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			return new Cells(rv,null);
+		}
+	}
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
new file mode 100644
index 0000000..3fa6508
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantAction.java
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.RolePermRequest;
+
+public class PermGrantAction extends Page {
+	
+	
+	public PermGrantAction(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,PermGrantForm.NAME, PermGrantForm.HREF, PermGrantForm.fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+				final Slot sType = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[0]);
+				final Slot sInstance = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[1]);
+				final Slot sAction = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[2]);
+				final Slot sRole = gui.env.slot(PermGrantForm.NAME+'.'+PermGrantForm.fields[3]);
+				
+				@Override
+				public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+					cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(final AuthGUI gui, final AuthzTrans trans,Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+
+							String type = trans.get(sType,null);
+							String instance = trans.get(sInstance,null);
+							String action = trans.get(sAction,null);
+							String role = trans.get(sRole,null);
+							
+							String lastPage = PermGrantForm.HREF 
+									+ "?type=" + type + "&instance=" + instance + "&action=" + action;
+							
+							// Run Validations
+							boolean fail = true;
+						
+							TimeTaken tt = trans.start("AAF Grant Permission to Role",Env.REMOTE);
+							try {
+								
+								final RolePermRequest grantReq = new RolePermRequest();
+								Pkey pkey = new Pkey();
+								pkey.setType(type);
+								pkey.setInstance(instance);
+								pkey.setAction(action);
+								grantReq.setPerm(pkey);
+								grantReq.setRole(role);
+								
+								fail = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Boolean>() {
+									@Override
+									public Boolean code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+										boolean fail = true;
+										Future<RolePermRequest> fgrant = client.create(
+												"/authz/role/perm",
+												gui.rolePermReqDF,
+												grantReq
+												);
+
+										if(fgrant.get(5000)) {
+											hgen.p("Permission has been granted to role.");
+											fail = false;
+										} else {
+											if (202==fgrant.code()) {
+												hgen.p("Permission Grant Request sent, but must be Approved before actualizing");
+												fail = false;
+											} else {
+												gui.writeError(trans, fgrant, hgen);
+											}
+										}
+										return fail;
+									}
+								});
+							} catch (Exception e) {
+								hgen.p("Unknown Error");
+								e.printStackTrace();
+							} finally {
+								tt.done();
+							}
+								
+							hgen.br();
+							hgen.incr("a",true,"href="+lastPage);
+							if (fail) {
+								hgen.text("Try again");
+							} else {
+								hgen.text("Grant this Permission to Another Role");
+							}
+							hgen.end();
+							hgen.js()
+								.text("alterLink('permgrant', '"+lastPage + "');")							
+								.done();
+
+						}
+					});
+				}
+			});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
new file mode 100644
index 0000000..b3b51f6
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermGrantForm.java
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import static com.att.xgen.html.HTMLGen.TABLE;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+public class PermGrantForm extends Page {
+	static final String HREF = "/gui/permgrant";
+	static final String NAME = "Permission Grant";
+	static final String fields[] = {"type","instance","action","role"};
+	
+	public PermGrantForm(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, fields,
+			new BreadCrumbs(breadcrumbs),
+			new NamedCode(true,"content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot type = gui.env.slot(NAME+".type");
+				final Slot instance = gui.env.slot(NAME+".instance");
+				final Slot action = gui.env.slot(NAME+".action");
+				final Slot role = gui.env.slot(NAME+".role");
+				// p tags not closing right using .p() - causes issues in IE8 password form - so using leaf for the moment
+				hgen.leaf("p").text("Choose a role to grant to this permission").end()
+					.incr("form","method=post");
+				Mark table = new Mark(TABLE);
+				hgen.incr(table);
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+						
+						Mark copyRoleJS = new Mark();
+						hgen.js(copyRoleJS);
+						hgen.text("function copyRole(role) {");
+						hgen.text("var txtRole = document.querySelector(\"#role\");");
+//						hgen.text("if (role==;");
+						hgen.text("txtRole.value=role;");
+						hgen.text("}");
+						hgen.end(copyRoleJS);
+						
+						String typeValue = trans.get(type, "");
+						String instanceValue = trans.get(instance, "");
+						String actionValue = trans.get(action, "");
+						String roleValue = trans.get(role,null);
+						List<String> myRoles = getMyRoles(gui, trans);
+						hgen
+						.input(fields[0],"Perm Type",true,"value="+typeValue,"disabled")
+						.input(fields[1],"Perm Instance",true,"value="+instanceValue,"disabled")
+						.input(fields[2],"Perm Action",true,"value="+actionValue,"disabled");
+						
+						// select & options are not an input type, so we must create table row & cell tags
+						Mark selectRow = new Mark();
+						hgen
+						.incr(selectRow, "tr")
+						.incr("td")
+						.incr("label", "for=myroles", "required").text("My Roles").end()
+						.end()
+						.incr("td")
+						.incr("select", "name=myroles", "id=myroles", "onchange=copyRole(this.value)")
+						.incr("option", "value=").text("Select one of my roles").end();
+						for (String role : myRoles) {
+							hgen.incr("option", "value="+role).text(role).end();
+						}
+						hgen
+						.incr("option", "value=").text("Other").end()					
+						.end(selectRow);
+						if(roleValue==null) {
+							hgen.input(fields[3],"Role", true, "placeholder=or type a role here");
+						} else {
+							hgen.input(fields[3],"Role",true, "value="+roleValue);
+						}
+						hgen.end();
+					}
+				});
+				hgen.end();
+				hgen.tagOnly("input", "type=submit", "value=Submit")
+				.end();
+
+			}
+		});
+	}
+		
+	private static List<String> getMyRoles(final AuthGUI gui, final AuthzTrans trans) {
+		List<String> myRoles = new ArrayList<String>();
+		try {
+			gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+				@Override
+				public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+					TimeTaken tt = trans.start("AAF get my roles",Env.REMOTE);
+					try {
+						Future<Roles> fr = client.read("/authz/roles/user/"+trans.user(),gui.rolesDF);
+						if(fr.get(5000)) {
+							tt.done();
+							tt = trans.start("Load Data", Env.SUB);
+							if (fr.value != null) for (Role r : fr.value.getRole()) {
+								myRoles.add(r.getName());
+							}
+						} else {
+							gui.writeError(trans, fr, null);
+						}
+					} finally {
+						tt.done();
+					}
+					return null;
+				}
+			});
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+		return myRoles;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
new file mode 100644
index 0000000..f360b0d
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermHistory.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class PermHistory extends Page {
+	static final String NAME="PermHistory";
+	static final String HREF = "/gui/permHistory";
+	static final String FIELDS[] = {"type","instance","action","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+		AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public PermHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot sType = gui.env.slot(NAME+".type");
+					final Slot sInstance = gui.env.slot(NAME+".instance");
+					final Slot sAction = gui.env.slot(NAME+".action");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String type = trans.get(sType, null);
+							String instance = trans.get(sInstance,null);
+							String action = trans.get(sAction,null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Permission [ " + type + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = PermDetail.HREF + "?type=" + type
+									+ "&instance=" + instance
+									+ "&action=" + action;
+							hgen.js()
+								.text("alterLink('permdetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a", "href=#advanced_search", "onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?type=" + type
+									+ "&instance=" + instance
+									+ "&action=" + action+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+						}
+					});
+				}
+			}
+
+			);
+		
+	}
+	
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot sType;
+		private Slot sDates;
+		
+		public Model(AuthzEnv env) {
+			sType = env.slot(NAME+".type");
+			sDates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(sType,null);
+			final String oDates = trans.get(sDates,null);
+			
+			if(oName==null) {
+				return Cells.EMPTY;
+			}
+			
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			String msg = null;
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						TimeTaken tt = trans.start("AAF Get History for Permission ["+oName+"]",Env.REMOTE);
+						try {
+							if (oDates != null) {
+								client.setQueryParams("yyyymm="+oDates);
+							}
+							Future<History> fh = client.read(
+								"/authz/hist/perm/"+oName,
+								gui.historyDF
+								);
+							
+							
+							if (fh.get(AuthGUI.TIMEOUT)) {
+								tt.done();
+								tt = trans.start("Load History Data", Env.SUB);
+								List<Item> histItems = fh.value.getItem();
+								
+								java.util.Collections.sort(histItems, new Comparator<Item>() {
+									@Override
+									public int compare(Item o1, Item o2) {
+										return o2.getTimestamp().compare(o1.getTimestamp());
+									}
+								});
+								
+								for (Item i : histItems) {
+									String user = i.getUser();
+									AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+											new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+									
+									rv.add(new AbsCell[] {
+											new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+											userCell,
+											new TextCell(i.getMemo())
+									});
+								}
+								
+							} else {
+								if (fh.code()==403) {
+									rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+								}
+							}
+						} finally {
+							tt.done();
+						}
+
+						return null;
+					}
+				});
+				
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+		return new Cells(rv,msg);
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
new file mode 100644
index 0000000..1bd3301
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/PermsShow.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Perm;
+import aaf.v2_0.Perms;
+
+/**
+ * Page content for My Permissions
+ * 
+ *
+ */
+public class PermsShow extends Page {
+	public static final String HREF = "/gui/myperms";
+	
+	public PermsShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyPerms",HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new Table<AuthGUI,AuthzTrans>("Permissions",gui.env.newTransNoAvg(),new Model(), "class=std"));
+	}
+
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Type","Instance","Action"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+			TimeTaken tt = trans.start("AAF Perms by User",Env.REMOTE);
+			try {
+				gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+					@Override
+					public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						Future<Perms> fp = client.read("/authz/perms/user/"+trans.user(), gui.permsDF);
+						if(fp.get(5000)) {
+							TimeTaken ttld = trans.start("Load Data", Env.SUB);
+							try {
+								if(fp.value!=null) {	
+									for(Perm p : fp.value.getPerm()) {
+										AbsCell[] sa = new AbsCell[] {
+											new RefCell(p.getType(),PermDetail.HREF
+													+"?type="+p.getType()
+													+"&amp;instance="+p.getInstance()
+													+"&amp;action="+p.getAction()),
+											new TextCell(p.getInstance()),
+											new TextCell(p.getAction())
+										};
+										rv.add(sa);
+									}
+								} else {
+									gui.writeError(trans, fp, null);
+								}
+							} finally {
+								ttld.done();
+							}
+						}
+						return null;
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			} finally {
+				tt.done();
+			}
+			return new Cells(rv,null);
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
new file mode 100644
index 0000000..43c2132
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RequestDetail.java
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.UUID;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Approval;
+import aaf.v2_0.Approvals;
+
+public class RequestDetail extends Page {
+	public static final String HREF = "/gui/requestdetail";
+	public static final String NAME = "RequestDetail";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
+	public static final String[] FIELDS = {"ticket"};
+
+	public RequestDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, FIELDS,
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Request Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Request Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		final long NUM_100NS_INTERVALS_SINCE_UUID_EPOCH = 0x01b21dd213814000L;
+		private static final String[] headers = new String[0];
+		private Slot sTicket;
+		public Model(AuthzEnv env) {
+			sTicket = env.slot(NAME+".ticket");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			Cells rv=Cells.EMPTY;
+			final String ticket = trans.get(sTicket, null);
+			if(ticket!=null) {
+				try {
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							TimeTaken tt = trans.start("AAF Approval Details",Env.REMOTE);
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							try {
+								Future<Approvals> fa = client.read(
+									"/authz/approval/ticket/"+ticket, 
+									gui.approvalsDF
+									);
+								
+								if(fa.get(AuthGUI.TIMEOUT)) {
+									if (!trans.user().equals(fa.value.getApprovals().get(0).getUser())) {
+										return Cells.EMPTY;
+									}
+									tt.done();
+									tt = trans.start("Load Data", Env.SUB);
+									boolean first = true;
+									for ( Approval approval : fa.value.getApprovals()) {
+										AbsCell[] approverLine = new AbsCell[4];
+										// only print common elements once
+										if (first) {
+											DateFormat createdDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+											UUID id = UUID.fromString(approval.getId());
+											
+											rv.add(new AbsCell[]{new TextCell("Ticket ID:"),new TextCell(approval.getTicket(),"colspan=3")});
+											rv.add(new AbsCell[]{new TextCell("Memo:"),new TextCell(approval.getMemo(),"colspan=3")});
+											rv.add(new AbsCell[]{new TextCell("Requested On:"), 
+													new TextCell(createdDF.format((id.timestamp() - NUM_100NS_INTERVALS_SINCE_UUID_EPOCH)/10000),"colspan=3")
+											});
+											rv.add(new AbsCell[]{new TextCell("Operation:"),new TextCell(decodeOp(approval.getOperation()),"colspan=3")});
+											String user = approval.getUser();
+											if (user.endsWith(CSP_ATT_COM)) {
+												rv.add(new AbsCell[]{new TextCell("User:"),
+														new RefCell(user,WEBPHONE + user.substring(0, user.indexOf("@")),"colspan=3")});
+											} else {
+												rv.add(new AbsCell[]{new TextCell("User:"),new TextCell(user,"colspan=3")});
+											}
+											
+											// headers for listing each approver
+											rv.add(new AbsCell[]{new TextCell(" ","colspan=4","class=blank_line")});
+											rv.add(new AbsCell[]{AbsCell.Null,
+													new TextCell("Approver","class=bold"), 
+													new TextCell("Type","class=bold"), 
+													new TextCell("Status","class=bold")});
+											approverLine[0] = new TextCell("Approvals:");
+											
+											first = false;
+										} else {
+										    approverLine[0] = AbsCell.Null;
+										}
+										
+										String approver = approval.getApprover();
+										String approverShort = approver.substring(0,approver.indexOf('@'));
+										
+										if (approver.endsWith(CSP_ATT_COM)) {
+											approverLine[1] = new RefCell(approver, WEBPHONE + approverShort);
+										} else {
+											approverLine[1] = new TextCell(approval.getApprover());
+										}
+										
+										String type = approval.getType();
+										if ("owner".equalsIgnoreCase(type)) {
+											type = "resource owner";
+										}
+										
+										approverLine[2] = new TextCell(type);
+										approverLine[3] = new TextCell(approval.getStatus());
+										rv.add(approverLine);
+									
+									}
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+								}
+							} finally {
+								tt.done();
+							}
+							return new Cells(rv,null);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+
+		private String decodeOp(String operation) {
+			if ("C".equalsIgnoreCase(operation)) {
+				return "Create";
+			} else if ("D".equalsIgnoreCase(operation)) {
+				return "Delete";
+			} else if ("U".equalsIgnoreCase(operation)) {
+				return "Update";
+			} else if ("G".equalsIgnoreCase(operation)) {
+				return "Grant";
+			} else if ("UG".equalsIgnoreCase(operation)) {
+				return "Un-Grant";
+			}
+			return operation;
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
new file mode 100644
index 0000000..d45813e
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleDetail.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.Role;
+import aaf.v2_0.Roles;
+
+/**
+ * Detail Page for Permissions
+ * 
+ *
+ */
+public class RoleDetail extends Page {
+	public static final String HREF = "/gui/roledetail";
+	public static final String NAME = "RoleDetail";
+	private static final String BLANK = "";
+
+	public RoleDetail(final AuthGUI gui, Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, NAME, HREF, new String[] {"role"},
+				new BreadCrumbs(breadcrumbs),
+				new Table<AuthGUI,AuthzTrans>("Role Details",gui.env.newTransNoAvg(),new Model(gui.env()),"class=detail")
+				);
+	}
+
+	/**
+	 * Implement the table content for Permissions Detail
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[0];
+		private Slot role;
+		public Model(AuthzEnv env) {
+			role = env.slot(NAME+".role");
+		}
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String pRole = trans.get(role, null);
+			Cells rv = Cells.EMPTY;
+			if(pRole!=null) {
+				try { 
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							rv.add(new AbsCell[]{new TextCell("Role:"),new TextCell(pRole)});
+							
+							TimeTaken tt = trans.start("AAF Role Details",Env.REMOTE);
+							try {
+								
+								Future<Roles> fr = client.read("/authz/roles/"+pRole,gui.rolesDF);
+								if(fr.get(AuthGUI.TIMEOUT)) {
+									tt.done();
+									tt = trans.start("Load Data", Env.SUB);
+									Role role = fr.value.getRole().get(0);
+									String desc = (role.getDescription()!=null?role.getDescription():BLANK);
+									rv.add(new AbsCell[]{new TextCell("Description:"),new TextCell(desc)});
+									boolean first=true;
+									for(Pkey r : role.getPerms()) {
+										if(first){
+											first=false;
+											rv.add(new AbsCell[] {
+													new TextCell("Associated Permissions:"),
+													new TextCell(r.getType() +
+															" | " + r.getInstance() +
+															" | " + r.getAction()
+															)
+												});
+										} else {
+											rv.add(new AbsCell[] {
+												AbsCell.Null,
+												new TextCell(r.getType() +
+														" | " + r.getInstance() +
+														" | " + r.getAction()
+														)
+											});
+										}
+									}
+									String historyLink = RoleHistory.HREF 
+											+ "?role=" + pRole;
+									rv.add(new AbsCell[] {new RefCell("See History",historyLink)});
+								} else {
+									rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***")});
+								}
+							} finally {
+								tt.done();
+							}
+							return new Cells(rv,null);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+	}
+}		
+		
\ No newline at end of file
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
new file mode 100644
index 0000000..8531132
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RoleHistory.java
@@ -0,0 +1,208 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.List;
+
+import com.att.authz.env.AuthzEnv;
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+import aaf.v2_0.History;
+import aaf.v2_0.History.Item;
+
+
+public class RoleHistory extends Page {
+	static final String NAME="RoleHistory";
+	static final String HREF = "/gui/roleHistory";
+	static final String FIELDS[] = {"role","dates"};
+	static final String WEBPHONE = "http://webphone.att.com/cgi-bin/webphones.pl?id=";
+	static enum Month { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, 
+		AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER };
+	
+	public RoleHistory(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME,HREF, FIELDS,
+			new BreadCrumbs(breadcrumbs),
+			new Table<AuthGUI,AuthzTrans>("History", gui.env.newTransNoAvg(),new Model(gui.env()),"class=std"),
+			new NamedCode(true, "content") {
+				@Override
+				public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+					final Slot role = gui.env.slot(NAME+".role");
+					cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+						@Override
+						public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {
+							String obRole = trans.get(role, null);
+							
+							// Use Javascript to make the table title more descriptive
+							hgen.js()
+							.text("var caption = document.querySelector(\".title\");")
+							.text("caption.innerHTML='History for Role [ " + obRole + " ]';")						
+							.done();
+							
+							// Use Javascript to change Link Target to our last visited Detail page
+							String lastPage = RoleDetail.HREF + "?role=" + obRole;
+							hgen.js()
+								.text("alterLink('roledetail', '"+lastPage + "');")							
+								.done();
+							
+							hgen.br();
+							hgen.leaf("a", "href=#advanced_search","onclick=divVisibility('advanced_search');").text("Advanced Search").end()
+								.divID("advanced_search", "style=display:none");
+							hgen.incr("table");
+								
+							addDateRow(hgen,"Start Date");
+							addDateRow(hgen,"End Date");
+							hgen.incr("tr").incr("td");
+							hgen.tagOnly("input", "type=button","value=Get History",
+									"onclick=datesURL('"+HREF+"?role=" + obRole+"');");
+							hgen.end().end();
+							hgen.end();
+							hgen.end();
+						}
+					});
+				}
+			}
+
+			);
+		
+	}
+	
+	private static void addDateRow(HTMLGen hgen, String s) {
+		hgen
+			.incr("tr")
+			.incr("td")
+			.incr("label", "for=month", "required").text(s+"*").end()
+			.end()
+			.incr("td")
+			.incr("select", "name=month"+s.substring(0, s.indexOf(' ')), "id=month"+s.substring(0, s.indexOf(' ')), "required")
+			.incr("option", "value=").text("Month").end();
+		for (Month m : Month.values()) {
+			if (Calendar.getInstance().get(Calendar.MONTH) == m.ordinal()) {
+				hgen.incr("option", "selected", "value="+(m.ordinal()+1)).text(m.name()).end();
+			} else {
+				hgen.incr("option", "value="+(m.ordinal()+1)).text(m.name()).end();
+			}
+		}
+		hgen.end()
+			.end()
+			.incr("td")
+			.tagOnly("input","type=number","id=year"+s.substring(0, s.indexOf(' ')),"required",
+					"value="+Calendar.getInstance().get(Calendar.YEAR), "min=1900", 
+					"max="+Calendar.getInstance().get(Calendar.YEAR),
+					"placeholder=Year").end()
+			.end();
+	}
+	
+	
+	/**
+	 * Implement the Table Content for History
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String CSP_ATT_COM = "@csp.att.com";
+		private static final String[] headers = new String[] {"Date","User","Memo"};
+		private Slot role;
+		private Slot dates;
+		
+		public Model(AuthzEnv env) {
+			role = env.slot(NAME+".role");
+			dates = env.slot(NAME+".dates");
+		}
+		
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			final String oName = trans.get(role,null);
+			final String oDates = trans.get(dates,null);
+			
+			Cells rv = Cells.EMPTY;
+			if(oName!=null) {
+				
+				try {
+					rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+						@Override
+						public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+							ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+							TimeTaken tt = trans.start("AAF Get History for Namespace ["+oName+"]",Env.REMOTE);
+							String msg = null;
+							try {
+								if (oDates != null) {
+									client.setQueryParams("yyyymm="+oDates);
+								}
+								Future<History> fh = client.read("/authz/hist/role/"+oName,gui.historyDF);
+								if (fh.get(AuthGUI.TIMEOUT)) {
+									tt.done();
+									tt = trans.start("Load History Data", Env.SUB);
+									List<Item> histItems = fh.value.getItem();
+									
+									java.util.Collections.sort(histItems, new Comparator<Item>() {
+										@Override
+										public int compare(Item o1, Item o2) {
+											return o2.getTimestamp().compare(o1.getTimestamp());
+										}
+									});
+									
+									for (Item i : histItems) {
+										String user = i.getUser();
+										AbsCell userCell = (user.endsWith(CSP_ATT_COM)?
+												new RefCell(user,WEBPHONE + user.substring(0,user.indexOf('@'))):new TextCell(user));
+										
+										rv.add(new AbsCell[] {
+												new TextCell(i.getTimestamp().toGregorianCalendar().getTime().toString()),
+												userCell,
+												new TextCell(i.getMemo())
+										});
+									}
+								} else {
+									if (fh.code()==403) {
+										rv.add(new AbsCell[] {new TextCell("You may not view History of Permission [" + oName + "]", "colspan = 3", "class=center")});
+									} else {
+										rv.add(new AbsCell[] {new TextCell("*** Data Unavailable ***", "colspan = 3", "class=center")});
+									}
+								}
+							} finally {
+								tt.done();
+							}	
+							return new Cells(rv,msg);
+						}
+					});
+				} catch (Exception e) {
+					trans.error().log(e);
+				}
+			}
+			return rv;
+		}
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
new file mode 100644
index 0000000..8b264df
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/RolesShow.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.Page;
+import com.att.authz.gui.Table;
+import com.att.authz.gui.Table.Cells;
+import com.att.authz.gui.table.AbsCell;
+import com.att.authz.gui.table.RefCell;
+import com.att.authz.gui.table.TextCell;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+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;
+
+import aaf.v2_0.UserRole;
+import aaf.v2_0.UserRoles;
+
+
+/**
+ * Page content for My Roles
+ * 
+ *
+ */
+public class RolesShow extends Page {
+	public static final String HREF = "/gui/myroles";
+	private static final String DATE_TIME_FORMAT = "yyyy-MM-dd";
+	private static SimpleDateFormat expiresDF;
+	
+	static {
+		expiresDF = new SimpleDateFormat(DATE_TIME_FORMAT);
+	}
+	
+	public RolesShow(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "MyRoles",HREF, NO_FIELDS,
+			new BreadCrumbs(breadcrumbs), 
+			new Table<AuthGUI,AuthzTrans>("Roles",gui.env.newTransNoAvg(),new Model(), "class=std"));
+	}
+
+	/**
+	 * Implement the Table Content for Permissions by User
+	 * 
+	 *
+	 */
+	private static class Model implements Table.Data<AuthGUI,AuthzTrans> {
+		private static final String[] headers = new String[] {"Role","Expires","Remediation","Actions"};
+
+		@Override
+		public String[] headers() {
+			return headers;
+		}
+		
+		@Override
+		public Cells get(final AuthGUI gui, final AuthzTrans trans) {
+			Cells rv = Cells.EMPTY;
+
+			try {
+				rv = gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Cells>() {
+					@Override
+					public Cells code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+						ArrayList<AbsCell[]> rv = new ArrayList<AbsCell[]>();
+						TimeTaken tt = trans.start("AAF Roles by User",Env.REMOTE);
+						try {
+							Future<UserRoles> fur = client.read("/authz/userRoles/user/"+trans.user(),gui.userrolesDF);
+							if (fur.get(5000)) {
+								if(fur.value != null) for (UserRole u : fur.value.getUserRole()) {
+									if(u.getExpires().compare(Chrono.timeStamp()) < 0) {
+										AbsCell[] sa = new AbsCell[] {
+												new TextCell(u.getRole() + "*", "class=expired"),
+												new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime()),"class=expired"),
+												new RefCell("Extend",
+														UserRoleExtend.HREF + "?user="+trans.user()+"&role="+u.getRole(), 
+														new String[]{"class=expired"}),
+												new RefCell("Remove",
+													UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole(), 
+													new String[]{"class=expired"})
+														
+											};
+											rv.add(sa);
+									} else {
+										AbsCell[] sa = new AbsCell[] {
+												new RefCell(u.getRole(),
+														RoleDetail.HREF+"?role="+u.getRole()),
+												new TextCell(expiresDF.format(u.getExpires().toGregorianCalendar().getTime())),
+												AbsCell.Null,
+												new RefCell("Remove",
+														UserRoleRemove.HREF + "?user="+trans.user()+"&role="+u.getRole())
+											};
+											rv.add(sa);
+									}
+								}
+							}
+							
+						} finally {
+							tt.done();
+						}
+						return new Cells(rv,null);
+					}
+				});
+			} catch (Exception e) {
+				trans.error().log(e);
+			}
+			return rv;
+		}
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
new file mode 100644
index 0000000..e54787b
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleExtend.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleExtend extends Page {
+	public static final String HREF = "/gui/urExtend";
+	static final String NAME = "Extend User Role";
+	static final String fields[] = {"user","role"};
+
+	public UserRoleExtend(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME, HREF, fields,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot sUser = gui.env.slot(NAME+".user");
+				final Slot sRole = gui.env.slot(NAME+".role");
+				
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {						
+						final String user = trans.get(sUser, "");
+						final String role = trans.get(sRole, "");
+
+						TimeTaken tt = trans.start("Request to extend user role",Env.REMOTE);
+						try {
+							gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+								@Override
+								public Void code(Rcli<?> client)throws CadiException, ConnectException, APIException {
+									Future<Void> fv = client.setQueryParams("request=true").update("/authz/userRole/extend/"+user+"/"+role);
+									if(fv.get(5000)) {
+										// not sure if we'll ever hit this
+										hgen.p("Extended User ["+ user+"] in Role [" +role+"]");
+									} else {
+										if (fv.code() == 202 ) {
+											hgen.p("User ["+ user+"] in Role [" +role+"] Extension sent for Approval");
+										} else {
+											gui.writeError(trans, fv, hgen);
+										}
+									}
+									return null;
+								}
+							});
+						} catch (Exception e) {
+							trans.error().log(e);
+							e.printStackTrace();
+						} finally {
+							tt.done();
+						}
+						
+						
+					}
+				});
+			}
+			
+		});
+	}
+}
+
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
new file mode 100644
index 0000000..fd2123c
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/UserRoleRemove.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+import java.net.ConnectException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.client.Future;
+import org.onap.aaf.cadi.client.Rcli;
+import org.onap.aaf.cadi.client.Retryable;
+import org.onap.aaf.inno.env.APIException;
+import org.onap.aaf.inno.env.Env;
+import org.onap.aaf.inno.env.Slot;
+import org.onap.aaf.inno.env.TimeTaken;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.html.HTMLGen;
+
+public class UserRoleRemove extends Page {
+	public static final String HREF = "/gui/urRemove";
+	static final String NAME = "Remove User Role";
+	static final String fields[] = {"user","role"};
+
+	public UserRoleRemove(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env,NAME, HREF, fields,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(final Cache<HTMLGen> cache, final HTMLGen hgen) throws APIException, IOException {
+				final Slot sUser = gui.env.slot(NAME+".user");
+				final Slot sRole = gui.env.slot(NAME+".role");
+				
+				
+				cache.dynamic(hgen, new DynamicCode<HTMLGen, AuthGUI, AuthzTrans>() {
+					@Override
+					public void code(AuthGUI gui, AuthzTrans trans,	Cache<HTMLGen> cache, HTMLGen hgen)	throws APIException, IOException {						
+						final String user = trans.get(sUser, "");
+						final String role = trans.get(sRole, "");
+
+						TimeTaken tt = trans.start("Request a user role delete",Env.REMOTE);
+						try {
+							gui.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {
+								@Override
+								public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {
+									Future<Void> fv = client.setQueryParams("request=true").delete(
+												"/authz/userRole/"+user+"/"+role,Void.class);
+									
+									if(fv.get(5000)) {
+										// not sure if we'll ever hit this
+										hgen.p("User ["+ user+"] Removed from Role [" +role+"]");
+									} else {
+										if (fv.code() == 202 ) {
+											hgen.p("User ["+ user+"] Removal from Role [" +role+"] sent for Approval");
+										} else {
+											gui.writeError(trans, fv, hgen);
+										}
+									}
+									return null;
+								}
+							});
+						} catch (Exception e) {
+							e.printStackTrace();
+						} finally {
+							tt.done();
+						}
+					}
+				});
+			}
+			
+		});
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
new file mode 100644
index 0000000..7c7bdb2
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/pages/WebCommand.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.pages;
+
+import java.io.IOException;
+
+import com.att.authz.env.AuthzTrans;
+import com.att.authz.gui.AuthGUI;
+import com.att.authz.gui.BreadCrumbs;
+import com.att.authz.gui.NamedCode;
+import com.att.authz.gui.Page;
+import org.onap.aaf.inno.env.APIException;
+import com.att.xgen.Cache;
+import com.att.xgen.DynamicCode;
+import com.att.xgen.Mark;
+import com.att.xgen.html.HTMLGen;
+
+public class WebCommand extends Page {
+	public static final String HREF = "/gui/cui";
+	
+	public WebCommand(final AuthGUI gui, final Page ... breadcrumbs) throws APIException, IOException {
+		super(gui.env, "Web Command Client",HREF, NO_FIELDS,
+				new BreadCrumbs(breadcrumbs),
+				new NamedCode(true, "content") {
+			@Override
+			public void code(Cache<HTMLGen> cache, HTMLGen hgen) throws APIException, IOException {
+				hgen.leaf("p","id=help_msg")
+					.text("Questions about this page? ")
+					.leaf("a", "href=http://wiki.web.att.com/display/aaf/Web+CUI+Usage", "target=_blank")
+					.text("Click here")
+					.end()
+					.text(". Type 'help' below for a list of AAF commands")
+					.end()
+					
+					.divID("console_and_options");
+				hgen.divID("console_area");				
+				hgen.end(); //console_area
+				
+				hgen.divID("options_link", "class=closed");
+				hgen.img("src=../../theme/options_down.png", "onclick=handleDivHiding('options',this);", 
+						"id=options_img", "alt=Options", "title=Options")					
+					.end(); //options_link
+				
+				hgen.divID("options");
+				cache.dynamic(hgen, new DynamicCode<HTMLGen,AuthGUI,AuthzTrans>() {
+					@Override
+					public void code(AuthGUI state, AuthzTrans trans, Cache<HTMLGen> cache, HTMLGen xgen)
+							throws APIException, IOException {
+						switch(browser(trans,trans.env().slot(getBrowserType()))) {
+							case ie:
+							case ieOld:
+								// IE doesn't support file save
+								break;
+							default:
+								xgen.img("src=../../theme/AAFdownload.png", "onclick=saveToFile();",
+										"alt=Save log to file", "title=Save log to file");
+						}
+//						xgen.img("src=../../theme/AAFemail.png", "onclick=emailLog();",
+//								"alt=Email log to me", "title=Email log to me");
+						xgen.img("src=../../theme/AAF_font_size.png", "onclick=handleDivHiding('text_slider',this);", 
+								"id=fontsize_img", "alt=Change text size", "title=Change text size");
+						xgen.img("src=../../theme/AAF_details.png", "onclick=selectOption(this,0);", 
+								"id=details_img", "alt=Turn on/off details mode", "title=Turn on/off details mode");
+						xgen.img("src=../../theme/AAF_maximize.png", "onclick=maximizeConsole(this);",
+								"id=maximize_img", "alt=Maximize Console Window", "title=Maximize Console Window");
+					}	
+				});
+
+				hgen.divID("text_slider");
+				hgen.tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('dec')", "value=-")
+					.tagOnly("input", "id=text_size_slider", "type=range", "min=75", "max=200", "value=100", 
+						"oninput=changeFontSize(this.value)", "onchange=changeFontSize(this.value)", "title=Change Text Size")
+					.tagOnly("input", "type=button", "class=change_font", "onclick=buttonChangeFontSize('inc')", "value=+")				
+					.end(); //text_slider
+
+				hgen.end(); //options
+				hgen.end(); //console_and_options
+				
+				hgen.divID("input_area");
+				hgen.tagOnly("input", "type=text", "id=command_field", 
+						"autocomplete=off", "autocorrect=off", "autocapitalize=off", "spellcheck=false",
+						"onkeypress=keyPressed()", "placeholder=Type your AAFCLI commands here", "autofocus")
+					.tagOnly("input", "id=submit", "type=button", "value=Submit", 
+							"onclick=http('put','../../gui/cui',getCommand(),callCUI);")
+					.end();
+
+				Mark callCUI = new Mark();
+				hgen.js(callCUI);
+				hgen.text("function callCUI(resp) {")
+					.text("moveCommandToDiv();")
+					.text("printResponse(resp);") 
+					.text("}");
+				hgen.end(callCUI);	
+			
+			}
+		});
+
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
new file mode 100644
index 0000000..eb91c22
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/AbsCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public abstract class AbsCell {
+	private static final String[] NONE = new String[0];
+	protected static final String[] CENTER = new String[]{"class=center"};
+
+	/**
+	 * Write Cell Data with HTMLGen generator
+	 * @param hgen
+	 */
+	public abstract void write(HTMLGen hgen);
+	
+	public final static AbsCell Null = new AbsCell() {
+		@Override
+		public void write(final HTMLGen hgen) {
+		}
+	};
+	
+	public String[] attrs() {
+		return NONE;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
new file mode 100644
index 0000000..4c270cf
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/ButtonCell.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class ButtonCell extends AbsCell {
+	private String[] attrs;
+	
+	public ButtonCell(String value, String ... attributes) {
+		attrs = new String[2+attributes.length];
+		attrs[0]="type=button";
+		attrs[1]="value="+value;
+		System.arraycopy(attributes, 0, attrs, 2, attributes.length);
+	}
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.incr("input",true,attrs).end();
+
+	}
+	
+	@Override
+	public String[] attrs() {
+		return AbsCell.CENTER;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
new file mode 100644
index 0000000..b4fa644
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RadioCell.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+public class RadioCell extends AbsCell {
+	private String[] attrs;
+	
+	public RadioCell(String name, String radioClass, String value, String ... attributes) {
+		attrs = new String[4+attributes.length];
+		attrs[0]="type=radio";
+		attrs[1]="name="+name;
+		attrs[2]="class="+radioClass;
+		attrs[3]="value="+value;
+		System.arraycopy(attributes, 0, attrs, 4, attributes.length);
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.incr("input",true,attrs).end();
+	}
+
+	@Override
+	public String[] attrs() {
+		return AbsCell.CENTER;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
new file mode 100644
index 0000000..4971983
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/RefCell.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write a Reference Link into a Cell
+ *
+ */
+public class RefCell extends AbsCell {
+	public final String name;
+	public final String href;
+	private String[] attrs;
+	
+	public RefCell(String name, String href, String... attributes) {
+		attrs = new String[attributes.length];
+		System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+		this.name = name;
+		this.href = href;
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.leaf(A,"href="+href).text(name);
+	}
+	
+	@Override
+	public String[] attrs() {
+		return attrs;
+	}
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
new file mode 100644
index 0000000..1c25361
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextAndRefCell.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import static com.att.xgen.html.HTMLGen.A;
+
+import com.att.xgen.html.HTMLGen;
+
+public class TextAndRefCell extends RefCell {
+
+	private String text;
+		
+	public TextAndRefCell(String text, String name, String href, String[] attributes) {
+		super(name, href, attributes);
+		this.text = text;
+	}
+
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.text(text);
+		hgen.leaf(A,"href="+href).text(name);
+	}
+
+}
diff --git a/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
new file mode 100644
index 0000000..d098792
--- /dev/null
+++ b/authz-gui/src/main/java/com/att/authz/gui/table/TextCell.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+package com.att.authz.gui.table;
+
+import com.att.xgen.html.HTMLGen;
+
+/**
+ * Write Simple Text into a Cell
+ *
+ */
+public class TextCell extends AbsCell {
+	public final String name;
+	private String[] attrs;
+	
+	public TextCell(String name, String... attributes) {
+		attrs = new String[attributes.length];
+		System.arraycopy(attributes, 0, attrs, 0, attributes.length);
+		this.name = name;
+	}
+	
+	@Override
+	public void write(HTMLGen hgen) {
+		hgen.text(name);
+	}
+	
+	@Override
+	public String[] attrs() {
+		return attrs;
+	}
+}
diff --git a/authz-gui/theme/AAF_details.png b/authz-gui/theme/AAF_details.png
new file mode 100644
index 0000000..5c18745
--- /dev/null
+++ b/authz-gui/theme/AAF_details.png
Binary files differ
diff --git a/authz-gui/theme/AAF_font_size.png b/authz-gui/theme/AAF_font_size.png
new file mode 100644
index 0000000..466cbfb
--- /dev/null
+++ b/authz-gui/theme/AAF_font_size.png
Binary files differ
diff --git a/authz-gui/theme/AAF_maximize.png b/authz-gui/theme/AAF_maximize.png
new file mode 100644
index 0000000..706603b
--- /dev/null
+++ b/authz-gui/theme/AAF_maximize.png
Binary files differ
diff --git a/authz-gui/theme/AAFdownload.png b/authz-gui/theme/AAFdownload.png
new file mode 100644
index 0000000..cebd952
--- /dev/null
+++ b/authz-gui/theme/AAFdownload.png
Binary files differ
diff --git a/authz-gui/theme/AAFemail.png b/authz-gui/theme/AAFemail.png
new file mode 100644
index 0000000..6d48776
--- /dev/null
+++ b/authz-gui/theme/AAFemail.png
Binary files differ
diff --git a/authz-gui/theme/aaf5.css b/authz-gui/theme/aaf5.css
new file mode 100644
index 0000000..920bdab
--- /dev/null
+++ b/authz-gui/theme/aaf5.css
@@ -0,0 +1,524 @@
+/*
+  Standard CSS for AAF
+*/
+
+html {
+	height: 100%;
+}
+
+body {
+	background-image:url('t_bubbles.jpg');
+	background-color: #FFFFFF;
+	background-repeat:no-repeat;
+	background-position: right top;
+	background-size:15em 4.3em;
+	color:#606060;
+	font-family: Verdana,Arial,Helvetica,sans-serif;
+	overflow: scroll;
+	}
+
+header h1,p {
+	margin: 4px auto;
+}
+
+header h1 {
+	display: inline;
+}
+
+header {
+	display: block;
+	color: #F13099;
+}
+
+p#version {
+	margin:0;
+	display:inline;
+	font-size: 0.75em;
+	float:right;
+	color: orange;
+	padding-right:4.2em;
+}
+
+header hr {
+	margin: 0;
+}
+
+hr {
+	border: 1px solid #C0C0C0;
+}
+
+#breadcrumbs {
+	padding: 5px 0 12px 0;
+}
+
+
+#breadcrumbs ul {
+	color: #DFEFFC;
+	margin: 0;
+	list-style-type:none;
+	padding: 0;
+}
+
+#breadcrumbs li {
+	border-width:2px;
+	margin: 3px 1px;
+	padding: 2px 9px;
+	border-style:solid;
+	border-top-left-radius: .8em;
+	border-bottom-left-radius: .8em;
+	background-color:#80C337;
+	display:inline;
+}
+
+#breadcrumbs a {
+	text-decoration:none;
+	color: white;
+}
+
+caption {
+	color:#FF7241;
+	text-align: center;
+	font-size:1.3em;
+	font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+}
+
+#Pages {
+	padding: 3px 2px 10px 4px;
+	background: linear-gradient(to right, #147AB3,#FFFFFF);
+}
+
+#Pages h3,
+#Pages h4,
+h5{
+	color: #909090;
+}
+ 
+form {
+	padding: 10px;
+	margin: 4px;
+}
+
+
+form input[id],select#myroles {
+	margin: 4px 0;
+	width: 150%;
+}
+
+form label {
+	margin: 4px 0;
+}
+
+form label[required] {
+	color: red;
+}
+
+form input[type=submit], form input[type=reset] {
+	font-size: 1.0em;
+	margin: 12px 0 0px 0;
+	color: #F13099;
+}
+
+p.preamble, p.notfound,.expedite_request {
+	display: block;
+	margin: 30px 0px 10px 0px;
+	font: italic bold 20px/30px Georgia, serif;
+	font-size: 110%;
+	color: #0079B8;
+}
+.expedite_request {
+	margin-top: 0;
+	color: #FF7241;
+}
+
+.subtext {
+	margin-left: 10px;
+	font-size: 75%;
+	font-style: italic;
+}
+
+#Pages a {
+	display:block;
+	font-weight:bold;
+	color:#FFFFFF;
+	background-color:#80C337;
+	text-decoration:none;
+	border-top-right-radius: .8em;
+	border-bottom-right-radius: .8em;
+	border-top-left-radius: .2em;
+	border-bottom-left-radius: .2em;
+	padding: 3px 40px 3px 10px;
+	margin: 4px;
+	width: 50%;
+}
+
+#footer {
+	background-color: #FF7200;
+	color: #FFFFFF; 
+	text-align:right;
+	font-size: 60%;
+	padding: 5px;
+	position:fixed;
+	bottom: 0px;
+	left: 0px;
+	right: 0px;
+}
+
+/* 
+  Standard Table, with Alternating Colors
+*/
+div.std {
+	vertical-align: top;
+}
+
+div.std table, div.stdform table {
+	position: relative;
+	border-collapse:collapse;
+	table-layout:auto;
+	left: 1.3%;
+	width: 98%;
+	margin-top: 5px;
+	bottom: 4px;
+	border-radius: 4px;
+}
+
+div.std td, div.stdform td {
+	font-size:.9em;
+}
+
+.center {
+	text-align: center;
+}
+
+.right {
+	text-align: right;
+	padding-right: 4px;
+}
+
+p.double {
+	line-height: 2em;
+}
+
+p.api_comment {
+	font-size: .9em;
+	text-indent: 6px;
+}
+
+p.api_contentType {
+	font-size: .8em;
+	text-indent: 6px;
+}
+
+p.api_label {
+	font-size: .9em;
+	font-style: italic;
+}
+
+div.std h1, div.std h2, div.std h3, div.std h4, div.std h5 {
+	text-indent: 7px;
+}
+	
+div.std td {
+	border:1px solid #A6C9E2;
+}
+	
+div.std th, div.stdform th {
+	background-color:#6FA7D1;
+	color:#FFFFFF;
+	}
+
+div.std tr.alt, div.stdform tr.alt {
+	background-color:#DFEFFC;
+}
+
+div.std a, div.stdform a {
+	/*color: #606060;*/
+	color: #147AB3;
+}
+
+td.head {
+	font-weight:bold;
+	text-align: center;
+}
+
+td.head a {
+	color:blue;
+}
+
+/* 
+  A Table representing 1 or more columns of text, i.e. Detail lists
+*/
+div.detail table {
+	width: 100%;
+}
+
+div.detail caption {
+	border-bottom: solid 1px #C0C0C0;
+}
+
+/*
+	Approval Form select all
+
+*/
+.selectAllButton {
+	background: transparent;
+	border:none;
+	color:blue;
+	text-decoration:underline;
+	font-weight:bold;
+	cursor:pointer;
+}
+
+
+/*
+	Begin Web Command Styling
+*/
+#console_and_options {
+	position:relative;
+}
+
+.maximized {
+	position:absolute;
+	top:0px;
+	bottom:50px;
+	left:0px;
+	right:0px;
+	z-index:1000;
+	background-color:white;
+}
+
+#console_area {
+	-webkit-border-radius: 15px;
+	-moz-border-radius: 15px;
+	border-radius: 15px;
+	background-color: black;
+	color: white;
+	font-family: "Lucida Console", Monaco, monospace;
+	overflow-y: scroll;
+	height: 300px;
+	min-width: 600px;
+	padding: 5px;	
+	resize: vertical;
+}
+
+.command,.bold {
+	font-weight: bold;
+}
+
+.command:before {
+	content: "> ";
+}
+
+.response{
+	font-style: italic;
+	font-size: 150%;
+}
+
+#input_area {
+	margin-top: 10px;	
+	clear: both;
+}
+
+#command_field, #submit {
+	font-size: 125%;
+	background-color: #333333;
+	color: white;
+	font-family: "Lucida Console", Monaco, monospace;
+	-webkit-border-radius: 1em;
+	-moz-border-radius: 1em;
+	border-radius: 1em;
+}
+
+#command_field {
+	width: 75%;
+	padding-left: 1em;
+}
+
+#submit {
+	background-color: #80C337;
+	padding: 0 5%;
+	float: right;
+}
+
+/*
+	Options Menu Styling for Web Command
+*/
+#options_link {
+	-webkit-border-radius: 0 0 20% 20%;
+	-moz-border-radius: 0 0 20% 20%;
+	border-radius: 0 0 20% 20%;
+	-webkit-transition: opacity 0.5s ease-in-out;
+	-moz-transition: opacity 0.5s ease-in-out;
+	-ms-transition: opacity 0.5s ease-in-out;
+	-o-transition: opacity 0.5s ease-in-out;
+	transition: opacity 0.5s ease-in-out;
+}
+
+.closed {
+	opacity: 0.5;
+	filter: alpha(opacity=50);
+}
+
+#options_link:hover, .open {
+	opacity: 1.0;
+	filter: alpha(opacity=100);
+}
+
+#options_link, #options {
+	background: white;
+	position:absolute;
+	top:0;
+	right:2em;
+	padding:0.1em;
+}
+
+#options > img {
+	cursor: pointer;
+	float: right;
+	padding: 0.2em;
+}
+
+.selected {
+	border: 3px solid orange;
+}
+
+#options, #text_slider {
+	display:none;
+	padding:0.5em;
+	-webkit-border-radius: 0 0 0 10px;
+	-moz-border-radius: 0 0 0 10px;
+	border-radius: 0 0 0 10px;
+}
+#text_slider {
+	clear:both;
+}
+
+/*
+	Button styling for changing text size
+*/
+.change_font {
+	border-top: 1px solid #96d1f8;
+	background: #65a9d7;
+	background: -webkit-gradient(linear, left top, left bottom, from(#3e779d), to(#65a9d7));
+	background: -webkit-linear-gradient(top, #3e779d, #65a9d7);
+	background: -moz-linear-gradient(top, #3e779d, #65a9d7);
+	background: -ms-linear-gradient(top, #3e779d, #65a9d7);
+	background: -o-linear-gradient(top, #3e779d, #65a9d7);
+	padding: 0 2px;
+	-webkit-border-radius: 50%;
+	-moz-border-radius: 50%;
+	border-radius: 50%;
+	-webkit-box-shadow: rgba(0,0,0,1) 0 1px 0;
+	-moz-box-shadow: rgba(0,0,0,1) 0 1px 0;
+	box-shadow: rgba(0,0,0,1) 0 1px 0;
+	text-shadow: rgba(0,0,0,.4) 0 1px 0;
+	color: white;
+	font-size: 14px;
+	font-family: monospace;
+	text-decoration: none;
+	vertical-align: middle;
+}
+.change_font:hover {
+	border-top-color: #28597a;
+	background: #28597a;
+	color: #ccc;
+}
+
+/*
+	Text Size Slider styling
+*/
+
+input[type=range] {
+  -webkit-appearance: none;
+  width: 60%;
+  margin: 0;
+}
+input[type=range]:focus {
+  outline: none;
+}
+input[type=range]::-webkit-slider-runnable-track {
+  width: 100%;
+  height: 4px;
+  cursor: pointer;
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+  background: #3071a9;
+  border-radius: 0.6px;
+  border: 0.5px solid #010101;
+}
+input[type=range]::-webkit-slider-thumb {
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+  border: 1px solid #000000;
+  height: 16px;
+  width: 16px;
+  border-radius: 30px;
+  background: #efffff;
+  cursor: pointer;
+  -webkit-appearance: none;
+  margin-top: -7.15px;
+}
+input[type=range]:focus::-webkit-slider-runnable-track {
+  background: #367ebd;
+}
+input[type=range]::-moz-range-track {
+  width: 100%;
+  height: 2.7px;
+  cursor: pointer;
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+  background: #3071a9;
+  border-radius: 0.6px;
+  border: 0.5px solid #010101;
+}
+input[type=range]::-moz-range-thumb {
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+  border: 1px solid #000000;
+  height: 16px;
+  width: 16px;
+  border-radius: 30px;
+  background: #efffff;
+  cursor: pointer;
+}
+input[type=range]::-ms-track {
+  width: 100%;
+  height: 2.7px;
+  cursor: pointer;
+  background: transparent;
+  border-color: transparent;
+  color: transparent;
+}
+input[type=range]::-ms-fill-lower {
+  background: #2a6495;
+  border: 0.5px solid #010101;
+  border-radius: 1.2px;
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+}
+input[type=range]::-ms-fill-upper {
+  background: #3071a9;
+  border: 0.5px solid #010101;
+  border-radius: 1.2px;
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+}
+input[type=range]::-ms-thumb {
+  box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+  border: 1px solid #000000;
+  height: 16px;
+  width: 16px;
+  border-radius: 30px;
+  background: #efffff;
+  cursor: pointer;
+  height: 2.7px;
+}
+input[type=range]:focus::-ms-fill-lower {
+  background: #3071a9;
+}
+input[type=range]:focus::-ms-fill-upper {
+  background: #367ebd;
+}
+.expired {
+	color: red;
+	background-color: pink;
+}
+.blank_line {
+	padding: 10px;
+}
+#filterByUser input {
+	display: inline;
+}
diff --git a/authz-gui/theme/aaf5Desktop.css b/authz-gui/theme/aaf5Desktop.css
new file mode 100644
index 0000000..b4aa02f
--- /dev/null
+++ b/authz-gui/theme/aaf5Desktop.css
@@ -0,0 +1,92 @@
+/*
+  Modifications for Desktop
+*/
+body {
+	background-size:23em 4.7em;
+}
+
+
+#breadcrumbs a:visited, #breadcrumbs a:link {
+	transition: padding .5s;
+}
+
+#breadcrumbs a:hover {
+	padding: 2px 2px 2px 30px;
+	transition: padding .5s;
+}
+
+#breadcrumbs, #inner {
+	margin: 3px;
+	width: 77%;
+	float: left;
+	min-width:500px;
+	background-color: #FFFFFF;
+	
+}
+
+#breadcrumbs li {
+	box-shadow: 3px 3px 2px #888888;
+}
+
+#Pages {
+	margin: 20px;
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#147AB3', endColorstr='#ffffff',GradientType=1 ); /*linear gradient for IE 6-9*/
+}
+
+#Pages a:visited, #Pages a:link {
+	padding: 3px 40px 3px 10px;
+	transition: padding .5s;
+	margin: 6px;
+	box-shadow: 3px 3px 2px #888888;
+}
+
+#Pages a:hover {
+	padding: 4px 80px 4px 15px;
+	transition: box-shadow padding .5s;
+	box-shadow: 4px 4px 3px #888888;
+}
+
+
+#inner {
+	padding: 7px;
+	background: #FFFFFF;
+	overflow: hidden;
+}
+
+div.std, form {
+	border: solid 2px #D0D0D0;
+	border-radius: 5px;
+	box-shadow: 10px 10px 5px #888888;
+}
+
+div.detail {
+	border: solid 2px #C0C0C0;
+	border-radius: 14px;
+	box-shadow: 10px 10px 5px #888888;
+}
+
+#nav {
+	display: inline-block;
+	position: absolute;
+	right: 2%;
+	left: 81%;
+}
+	
+#nav h2 {
+	color: #FF7200;
+	font-size: 1.2em;
+	font-family: Verdana,Arial,Helvetica,sans-serif;
+	font-style: italic;
+	font-weight: normal;
+	
+}
+
+#nav ul {
+	font-style:italic; 
+	font-size: .8em;
+	font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+	color: #067ab4;
+	list-style-type: square;
+	margin: 0;
+	padding: 0;
+}
diff --git a/authz-gui/theme/aaf5iPhone.css b/authz-gui/theme/aaf5iPhone.css
new file mode 100644
index 0000000..c356983
--- /dev/null
+++ b/authz-gui/theme/aaf5iPhone.css
@@ -0,0 +1,38 @@
+/*
+  Modifications for iPhone
+*/
+body {
+	zoom: 210%;
+}
+
+#breadcrumbs {
+	font-size: .9em;
+}
+
+
+div.std table {
+	margin: 0 0 20px 0;
+	zoom: 130%
+}
+	
+
+div.stdform th {
+	font-size: 9px;
+}
+
+#content input {
+	font-size: 1.3em;
+}
+
+
+#Pages a {
+	font-size: 1.3em;
+	width: 75%;
+	height:35px;
+}
+
+#nav {
+	display: none; 
+}
+
+
diff --git a/authz-gui/theme/aafOldIE.css b/authz-gui/theme/aafOldIE.css
new file mode 100644
index 0000000..5910c5c
--- /dev/null
+++ b/authz-gui/theme/aafOldIE.css
@@ -0,0 +1,162 @@
+/*
+  Modifications for non-html5 IE
+*/
+body {
+	background-size:23em 4.7em;
+}
+
+
+body h1 {
+	margin: 4px auto;
+	color: #F13099;
+}
+
+#footer {
+	background-color: #FF7200;
+	color: #FFFFFF;
+	text-align:right;
+	font-size: 60%;
+	padding: 5px;
+	position:fixed;
+	bottom: 0px;
+	left: 0px;
+	right: 0px;
+}
+
+#breadcrumbs a:visited, #breadcrumbs a:link {
+	transition: padding .5s;
+}
+
+#breadcrumbs a:hover {
+	padding: 2px 2px 2px 30px;
+	transition: padding .5s;
+}
+
+#breadcrumbs, #content {
+	margin: 3px;
+}
+
+#breadcrumbs, #inner {
+	margin: 3px;
+	width: 77%;
+	float: left;
+	min-width:500px;
+	background-color: #FFFFFF;
+}
+
+
+#breadcrumbs li {
+	box-shadow: 3px 3px 2px #888888;
+}
+
+#inner {
+	padding: 10px;
+	overflow: hidden;
+}
+
+#inner form {
+	border: solid 2px #D0D0D0;
+}
+
+#inner form input[id] {
+	margin: 4px 0;
+}
+
+#inner form label {
+	margin: 4px 0;
+}
+
+#inner form label[required] {
+	color: red;
+}
+
+#inner form input[type=submit] {
+	font-size: 1.0em;
+	margin: 12px 0 0px 0;
+	color: #F13099;
+}
+
+p.preamble, p.notfound {
+	display: block;
+	margin: 30px 0px 10px 0px;
+	font: italic bold 20px/30px Georgia, serif;
+	font-size: 110%;
+	color: #0079B8;
+}
+
+
+#Pages {
+	margin: 20px;
+	filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#147AB3', endColorstr='#ffffff',GradientType=1 ); /*linear gradient for IE 6-9*/
+}
+
+#Pages a:visited, #Pages a:link {
+	display: block;
+	padding: 3px 40px 3px 10px;
+	transition: padding .5s;
+	margin: 6px;
+	box-shadow: 3px 3px 2px #888888;
+ 	background-color: #98bf21;
+	text-decoration: none;
+	color: white;
+	font-weight: bold;
+}
+
+#Pages a:hover {
+	padding: 4px 80px 4px 20px;
+	transition: box-shadow padding 1s;
+	box-shadow: 4px 4px 3px #888888;
+}
+
+tr {
+	font-size: .9em;
+}
+
+tr.alt {
+	background-color: #EEF0F0;
+}
+
+#nav {
+
+	display: block;
+	position: absolute;
+	top: 175px;
+	right: 2%;
+	left: 81%;
+	z-index=1;
+	clear: both;
+}
+
+	
+#nav h2 {
+	color: #FF7200;
+	font-size: 1.2em;
+	font-family: Verdana,Arial,Helvetica,sans-serif;
+	font-style: italic;
+	font-weight: normal;
+	
+}
+
+#nav ul {
+	font-style:italic; 
+	font-size: .8em;
+	font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
+	color: #067ab4;
+	list-style-type: square;
+	margin: 0;
+	padding: 0;
+}
+
+div.std {
+	border: solid 2px #D0D0D0;
+	border-radius: 5px;
+	box-shadow: 10px 10px 5px #888888;
+}
+
+
+div.detail {
+	border: solid 2px #C0C0C0;
+	border-radius: 14px;
+	box-shadow: 10px 10px 5px #888888;
+}
+
diff --git a/authz-gui/theme/aaf_1_0.xsd b/authz-gui/theme/aaf_1_0.xsd
new file mode 100644
index 0000000..a71e2ea
--- /dev/null
+++ b/authz-gui/theme/aaf_1_0.xsd
@@ -0,0 +1,150 @@
+<!-- Used by AAF (ATT inc 2013) -->
+<xs:schema xmlns:aaf="urn:aaf:v1_0" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:aaf:v1_0" elementFormDefault="qualified">
+	<xs:element name="error">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="response_data" type="xs:string"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:element name="bool">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="value" type="xs:boolean"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:complexType name="permkey">
+		<xs:sequence>
+			<xs:element name="name" type="xs:string"/>
+			<xs:element name="type" type="xs:string"/>
+			<xs:element name="action" type="xs:string"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="permkeys">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="keys" type="aaf:permkey" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:complexType name="user">
+		<xs:sequence>
+			<xs:element name="userName" type="xs:string"/>
+			<xs:element name="roleName" type="xs:string"/>
+			<xs:element name="userType" type="xs:string"/>
+			<xs:element name="createUser" type="xs:string"/>
+			<xs:element name="createTimestamp" type="xs:string"/>
+			<xs:element name="modifyUser" type="xs:string"/>
+			<xs:element name="modifyTimestamp" type="xs:string"/>
+			<xs:element ref="aaf:roles" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:complexType name="role">
+		<xs:sequence>
+			<xs:element name="userName" type="xs:string"/>
+			<xs:element name="roleName" type="xs:string"/>
+			<xs:element name="userType" type="xs:string"/>
+			<xs:element name="createUser" type="xs:string"/>
+			<xs:element name="createTimestamp" type="xs:string"/>
+			<xs:element name="modifyUser" type="xs:string"/>
+			<xs:element name="modifyTimestamp" type="xs:string"/>
+			<xs:element ref="aaf:permissions" minOccurs="0" maxOccurs="unbounded"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="roles">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="roles" type="aaf:role" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	<xs:complexType name="permission">
+		<xs:complexContent>
+			<xs:extension base="aaf:permkey">
+				<xs:sequence>
+					<xs:element name="grantedRole" type="xs:string"/>
+					<xs:element name="createUser" type="xs:string"/>
+					<xs:element name="createTimestamp" type="xs:string"/>
+					<xs:element name="modifyUser" type="xs:string"/>
+					<xs:element name="modifyTimestamp" type="xs:string"/>
+					<xs:element name="grantingRole" type="xs:string"/>
+				</xs:sequence>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+	<xs:element name="permissions">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="permissions" type="aaf:permission" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+		<xs:complexType name="delg">
+		<xs:sequence>
+			<xs:element name="user" type="xs:string"/>
+			<xs:element name="delegate" type="xs:string"/>
+			<xs:element name="start" type="xs:date"/>
+			<xs:element name="end" type="xs:date"/>
+		</xs:sequence>
+	</xs:complexType>
+	<xs:element name="delgs">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="delgs" type="aaf:delg" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name="cred">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="id" type="xs:string"/>
+				<xs:choice >
+					<xs:element name="password" type="xs:string" />
+					<xs:element name="cert" type = "xs:hexBinary" />
+				</xs:choice>
+				<xs:element name="start" type="xs:date" />
+				<xs:element name="end" type="xs:date" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+	<!-- 
+	Approvals
+ 	-->
+ 	<xs:complexType name="approval">
+	   <xs:sequence>
+	       <xs:element name="user" type="xs:string"/>
+	       <xs:element name="role" type="xs:string"/>
+	       <xs:element name="status">
+			  <xs:simpleType>
+			    <xs:restriction base="xs:string">
+			      <xs:enumeration value="approve"/>
+			      <xs:enumeration value="reject"/>
+			    </xs:restriction>
+			  </xs:simpleType>
+		   </xs:element> 	
+	   </xs:sequence>
+	</xs:complexType>
+	<xs:element name="approvals">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="approvals" type="aaf:approval" minOccurs="1" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+	<!-- 
+		Users 
+	-->	
+	<xs:element name="users">
+		<xs:complexType>
+		   <xs:sequence>
+		       <xs:element name="id" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+		   </xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+</xs:schema>
+
diff --git a/authz-gui/theme/aaf_2_0.xsd b/authz-gui/theme/aaf_2_0.xsd
new file mode 100644
index 0000000..95c8ff9
--- /dev/null
+++ b/authz-gui/theme/aaf_2_0.xsd
@@ -0,0 +1,394 @@
+<!-- Used by AAF (ATT inc 2013) -->
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	xmlns:aaf="urn:aaf:v2_0" 
+	targetNamespace="urn:aaf:v2_0" 
+	elementFormDefault="qualified">
+	
+<!-- 
+	Note: jan 22, 2015.  Deprecating the "force" element in the "Request" Structure.  Do that
+	with Query Params. 
+	
+	Eliminate in 3.0 
+ -->
+<!--
+	Errors
+	Note: This Error Structure has been made to conform to the AT&T TSS Policies
+	
+	 
+ -->
+	<xs:element name="error">
+		<xs:complexType>
+			<xs:sequence>
+				<!--
+				Unique message identifier of the format ‘ABCnnnn’ where ‘ABC’ is
+					either ‘SVC’ for Service Exceptions or ‘POL’ for Policy Exception.
+					Exception numbers may be in the	range of 0001 to 9999 where :
+					* 0001 to 0199 are reserved for	common exception messages
+					* 0200 to 0999 are reserved for Parlay Web Services specification use
+					* 1000-9999 are available for exceptions 
+				 -->
+				<xs:element name="messageId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+				
+				<!-- 
+				Message text, with replacement
+					variables marked with %n, where n is
+					an index into the list of <variables>
+					elements, starting at 1
+				 -->
+				<xs:element name="text" type="xs:string" minOccurs="1" maxOccurs="1"/>
+				
+				<!-- 
+				List of zero or more strings that
+					represent the contents of the variables
+					used by the message text. -->
+				<xs:element name="variables" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+<!-- 
+	Requests
+ -->
+	<xs:complexType name="Request">
+		<xs:sequence>
+			<xs:element name="start" type="xs:dateTime" minOccurs="1" maxOccurs="1" />
+			<xs:element name="end" type="xs:date" minOccurs="1" maxOccurs="1"/>
+			<!-- Deprecated.  Use Query Command 
+			<xs:element name="force" type="xs:string" minOccurs="1" maxOccurs="1" default="false"/>
+			-->
+		</xs:sequence>
+	</xs:complexType>
+
+<!-- 
+	Permissions 
+-->	
+	<xs:complexType name = "pkey">
+		<xs:sequence>
+			<xs:element name="type" type="xs:string"/>
+			<xs:element name="instance" type="xs:string"/>
+			<xs:element name="action" type="xs:string"/>
+		</xs:sequence>
+	</xs:complexType>
+
+	<xs:element name="permKey">
+		<xs:complexType >
+			<xs:complexContent>
+				<xs:extension base="aaf:pkey" />
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name="perm">
+		<xs:complexType >
+			<xs:complexContent>
+				<xs:extension base="aaf:pkey">
+					<xs:sequence>					
+						<xs:element name="roles" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+						<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+ 						<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name="perms">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="aaf:perm" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="permRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="type" type="xs:string"/>
+						<xs:element name="instance" type="xs:string"/>
+						<xs:element name="action" type="xs:string"/>
+						<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+						<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+
+
+<!-- 
+	Roles 
+-->	
+	<xs:complexType name="rkey">
+		<xs:sequence>
+			<xs:element name="name" type="xs:string"/>
+		</xs:sequence>
+	</xs:complexType>
+	
+	<xs:element name="roleKey">
+		<xs:complexType >
+			<xs:complexContent>
+				<xs:extension base="aaf:rkey" />
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="role">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:rkey">
+					<xs:sequence>
+						<xs:element name="perms" type="aaf:pkey" minOccurs="0" maxOccurs="unbounded"/>
+						<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+						<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name="roles">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element ref="aaf:role" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="roleRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+						<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+						<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="userRoleRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="user" type="xs:string" minOccurs="1" maxOccurs="1"/>
+						<xs:element name="role" type="xs:string" minOccurs="1" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name="rolePermRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="perm" type="aaf:pkey" minOccurs="1" maxOccurs="1"/>
+						<xs:element name="role" type="xs:string" minOccurs="1" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+
+	<xs:element name="nsRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="name" type="xs:string" minOccurs="1" maxOccurs="1"/>
+						<xs:element name="admin" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
+						<xs:element name="responsible" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
+						<xs:element name="scope" type="xs:int" minOccurs="0" maxOccurs="1"/>
+						<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+						<xs:element name="description" type="xs:string" minOccurs="0" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+	<xs:element name = "nss">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name = "ns" minOccurs="0" maxOccurs="unbounded">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name = "name" type = "xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name = "responsible" type = "xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name = "admin" type = "xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<!-- Note: feb 23, 2015.  Added description field. Verify backward compatibility. JR -->
+							<xs:element name = "description" type = "xs:string" minOccurs="0" maxOccurs="1"/>
+						</xs:sequence>
+					</xs:complexType>
+				</xs:element>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+<!-- 
+	Users 
+-->	
+	<xs:element name="users">
+		<xs:complexType>
+			<xs:sequence>
+		   		<xs:element name="user" minOccurs="0" maxOccurs="unbounded">
+		   			<xs:complexType>
+		   				<xs:sequence>
+				       		<xs:element name="id" type="xs:string"  minOccurs="1" maxOccurs="1" />
+				       		<xs:element name="expires" type="xs:date" minOccurs="1" maxOccurs="1" />
+		   				</xs:sequence>
+		   			</xs:complexType>
+		   		</xs:element>
+		   	</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+
+<!-- 
+	Credentials 
+-->	
+	<xs:element name="credRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+						<xs:element name="id" type="xs:string"/>
+						<xs:element name="type" type="xs:int" minOccurs="0" maxOccurs="1"/>
+						<xs:choice >
+							<xs:element name="password" type="xs:string" />
+							<xs:element name="entry" type="xs:string" />
+						</xs:choice>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+	
+<!--
+	History 
+ -->
+ 	<xs:element name="history">
+ 		<xs:complexType>
+ 			<xs:sequence>
+ 				<xs:element name="item" minOccurs="0" maxOccurs="unbounded">
+			 		<xs:complexType>
+			 			<xs:sequence>
+			 				<xs:element name="YYYYMM" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="timestamp" type="xs:dateTime" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="subject" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="target" type = "xs:string" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="action" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="memo" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			 				<xs:element name="user" type="xs:string" minOccurs="1" maxOccurs="1"/>
+			 			</xs:sequence>
+			 		</xs:complexType>
+			 	</xs:element>
+		 	</xs:sequence>
+		 </xs:complexType>
+ 	</xs:element>
+ 
+<!-- 
+	Approvals
+ -->
+ 	<xs:complexType name="approval">
+	   <xs:sequence>
+	   	   <!-- Note, id is set by system -->
+	   	   <xs:element name="id" type="xs:string" minOccurs="0" maxOccurs="1"/>
+	   	   <xs:element name="ticket" type="xs:string"/>
+	       <xs:element name="user" type="xs:string"/>
+	       <xs:element name="approver" type="xs:string"/>
+	       <xs:element name="type" type="xs:string"/>
+	       <xs:element name="memo" type="xs:string"/>
+	       <xs:element name="updated" type="xs:dateTime"/>
+	       <xs:element name="status">
+			  <xs:simpleType>
+			    <xs:restriction base="xs:string">
+			      <xs:enumeration value="approve"/>
+			      <xs:enumeration value="reject"/>
+			      <xs:enumeration value="pending"/>
+			    </xs:restriction>
+			  </xs:simpleType>
+		   </xs:element> 	
+		   <xs:element name="operation">
+			  <xs:simpleType>
+			    <xs:restriction base="xs:string">
+			      <xs:enumeration value="C"/>
+			      <xs:enumeration value="U"/>
+			      <xs:enumeration value="D"/>
+			      <xs:enumeration value="G"/>
+			      <xs:enumeration value="UG"/>
+			    </xs:restriction>
+			  </xs:simpleType>
+		   </xs:element> 	
+	   </xs:sequence>
+	</xs:complexType>
+	<xs:element name="approvals">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="approvals" type="aaf:approval" minOccurs="1" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+<!-- 
+	Delegates 
+-->	
+	<xs:complexType name="delg">
+	   <xs:sequence>
+	       <xs:element name="user" type="xs:string"/>
+	       <xs:element name="delegate" type="xs:string"/>
+	       <xs:element name="expires" type="xs:date"/>
+	   </xs:sequence>
+	</xs:complexType>
+	
+	<xs:element name="delgRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="aaf:Request">
+					<xs:sequence>
+				       <xs:element name="user" type="xs:string" minOccurs="1" maxOccurs="1"/>
+				       <xs:element name="delegate" type="xs:string" minOccurs="1" maxOccurs="1"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+
+	<xs:element name="delgs">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="delgs" type="aaf:delg" minOccurs="0" maxOccurs="unbounded"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+	<!-- jg 3/11/2015 New for 2.0.8 -->
+	<xs:element name="api">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="meth" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="path" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="param" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="desc" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="comments" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="contentType" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="expected" type="xs:int" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="explicitErr" type="xs:int" minOccurs="0" maxOccurs="unbounded"/>
+						</xs:sequence>	
+					</xs:complexType>
+				</xs:element>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+</xs:schema>
\ No newline at end of file
diff --git a/authz-gui/theme/comm.js b/authz-gui/theme/comm.js
new file mode 100644
index 0000000..5a1ac4d
--- /dev/null
+++ b/authz-gui/theme/comm.js
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+function http(meth, sURL, sInput, func) {
+	if (sInput != "") { 
+		var http;
+		if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
+		  http=new XMLHttpRequest();
+		} else {// code for IE6, IE5
+		  http=new ActiveXObject('Microsoft.XMLHTTP');
+		}
+	
+		http.onreadystatechange=function() {
+		  if(http.readyState==4 && http.status == 200) {
+			 func(http.responseText)
+		  }
+		  // Probably want Exception code too.
+		}
+		
+		http.open(meth,sURL,false);
+		http.setRequestHeader('Content-Type','text/plain;charset=UTF-8');
+		http.send(sInput);
+	}
+}
\ No newline at end of file
diff --git a/authz-gui/theme/common.js b/authz-gui/theme/common.js
new file mode 100644
index 0000000..e9af8fe
--- /dev/null
+++ b/authz-gui/theme/common.js
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+Object.defineProperty(Element.prototype, 'outerHeight', {
+    'get': function(){
+        var height = this.clientHeight;
+        height += getStyle(this,'marginTop');
+        height += getStyle(this,'marginBottom');
+        height += getStyle(this,'borderTopWidth');
+        height += getStyle(this,'borderBottomWidth');
+        return height;
+    }
+});
+
+if (document.addEventListener) {
+	document.addEventListener('DOMContentLoaded', function () {
+		var height = document.querySelector("#footer").outerHeight;
+		document.querySelector("#inner").setAttribute("style",
+				"margin-bottom:" + height.toString()+ "px");
+	});
+} else {
+	window.attachEvent("onload", function () {
+		var height = document.querySelector("#footer").outerHeight;
+		document.querySelector("#inner").setAttribute("style",
+				"margin-bottom:" + height.toString()+ "px");
+	});
+}
+
+
+
+function getStyle(el, prop) {
+	var result = el.currentStyle ? el.currentStyle[prop] :
+		document.defaultView.getComputedStyle(el,"")[prop];
+	if (parseInt(result,10))
+		return parseInt(result,10);
+	else
+		return 0;
+}
+
+function divVisibility(divID) {
+	var element = document.querySelector("#"+divID);
+	if (element.style.display=="block")
+		element.style.display="none";
+	else
+		element.style.display="block";
+}
+
+function datesURL(histPage) {
+	var validated=true;
+	var yearStart = document.querySelector('#yearStart').value;
+	var yearEnd = document.querySelector('#yearEnd').value;
+	var monthStart = document.querySelector('#monthStart').value;
+	var monthEnd = document.querySelector('#monthEnd').value;
+	if (monthStart.length == 1) monthStart = 0 + monthStart;
+	if (monthEnd.length == 1) monthEnd = 0 + monthEnd;
+
+	validated &= validateYear(yearStart);
+	validated &= validateYear(yearEnd);
+	validated &= validateMonth(monthStart);
+	validated &= validateMonth(monthEnd);
+	
+	if (validated) window.location=histPage+"&dates="+yearStart+monthStart+"-"+yearEnd+monthEnd;
+	else alert("Please correct your date selections");
+}
+
+function userFilter(approvalPage) {
+	var user = document.querySelector('#userTextBox').value;
+	if (user != "")
+		window.location=approvalPage+"?user="+user;
+	else
+		window.location=approvalPage;
+}
+
+function validateYear(year) {
+	var today = new Date();
+	if (year >= 1900 && year <= today.getFullYear()) return true;
+	else return false;
+}
+
+function validateMonth(month) {
+	if (month) return true;
+	else return false;
+}
+
+function alterLink(breadcrumbToFind, newTarget) {
+	var breadcrumbs = document.querySelector("#breadcrumbs").getElementsByTagName("A");
+	for (var i=0; i< breadcrumbs.length;i++) {
+		var breadcrumbHref = breadcrumbs[i].getAttribute('href');
+		if (breadcrumbHref.indexOf(breadcrumbToFind)>-1) 
+			breadcrumbs[i].setAttribute('href', newTarget);
+	}
+}
+
+// clipBoardData object not cross-browser supported. Only IE it seems
+function copyToClipboard(controlId) { 
+    var control = document.getElementById(controlId); 
+    if (control == null) { 
+    	alert("ERROR - control not found - " + controlId); 
+    } else { 
+    	var controlValue = control.href; 
+    	window.clipboardData.setData("text/plain", controlValue); 
+    	alert("Copied text to clipboard : " + controlValue); 
+    } 
+}
diff --git a/authz-gui/theme/console.js b/authz-gui/theme/console.js
new file mode 100644
index 0000000..e35becf
--- /dev/null
+++ b/authz-gui/theme/console.js
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2016 AT&T Intellectual Property. All rights reserved.
+ *******************************************************************************/
+function getCommand() {
+	if(typeof String.prototype.trim !== 'function') {
+		String.prototype.trim = function() {
+			return this.replace(/^\s+|\s+$/g, ''); 
+		};
+	}
+
+	var cmds = [];
+	cmds = document.querySelector("#command_field").value.split(" ");
+	var cleanCmd = "";
+	if (document.querySelector("#details_img").getAttribute("class") == "selected") 
+		cleanCmd += "set details=true ";
+	for (var i = 0; i < cmds.length;i++) {
+		var trimmed = cmds[i].trim();
+		if (trimmed != "")
+			cleanCmd += trimmed + " ";
+	}
+	
+	return cleanCmd.trim();
+}
+
+function moveCommandToDiv() {
+
+	var textInput = document.querySelector("#command_field");
+	var content = document.createTextNode(textInput.value);
+	var parContent = document.createElement("p");
+	var consoleDiv = document.querySelector("#console_area");
+	var commandCount = consoleDiv.querySelectorAll(".command").length;
+	parContent.setAttribute("class", "command");
+	parContent.appendChild(content);
+	consoleDiv.appendChild(parContent);
+
+	textInput.value = "";
+}
+
+function printResponse(response) {
+	var parContent = document.createElement("p");
+	parContent.setAttribute("class", "response");
+	var preTag = document.createElement("pre");
+	parContent.appendChild(preTag);
+	var content = document.createTextNode(response);
+	preTag.appendChild(content);
+	var consoleDiv = document.querySelector("#console_area");
+	consoleDiv.appendChild(parContent);
+	
+	consoleDiv.scrollTop = consoleDiv.scrollHeight;
+}
+
+function clearHistory() {
+	var consoleDiv = document.querySelector("#console_area");
+	var curr;
+	while (curr=consoleDiv.firstChild) {
+		consoleDiv.removeChild(curr);
+	}
+	document.querySelector("#command_field").value = "";
+	currentCmd = 0;
+}
+
+function buttonChangeFontSize(direction) {
+	var slider = document.querySelector("#text_size_slider");
+	var currentSize = parseInt(slider.value);
+	var newSize;
+	if (direction == "inc") {
+		newSize = currentSize + 10;
+	} else {
+		newSize = currentSize - 10;
+	}
+	if (newSize > slider.max) newSize = parseInt(slider.max);
+	if (newSize < slider.min) newSize = parseInt(slider.min);
+	slider.value = newSize;
+	changeFontSize(newSize);
+}
+
+function changeFontSize(size) {
+	var consoleDiv = document.querySelector("#console_area");
+	consoleDiv.style.fontSize = size + "%";
+}
+
+function handleDivHiding(id, img) {
+	var options_link = document.querySelector("#options_link");
+	var divHeight = toggleVisibility(document.querySelector("#"+id));
+
+	if (id == 'options') {
+		if (options_link.getAttribute("class") == "open") {
+			changeImg(document.querySelector("#options_img"), "../../theme/options_down.png");
+			options_link.setAttribute("class", "closed");
+		} else {
+			changeImg(document.querySelector("#options_img"), "../../theme/options_up.png");
+			options_link.setAttribute("class", "open");
+		}
+		moveToggleImg(options_link, divHeight);
+	} else { //id=text_slider
+		selectOption(img,divHeight);
+	}
+
+}
+
+function selectOption(img, divHeight) {
+	var options_link = document.querySelector("#options_link");
+	var anySelected;
+	if (img.getAttribute("class") != "selected") {
+		anySelected = document.querySelectorAll(".selected").length>0;
+		if (anySelected == false)
+			divHeight += 4;
+		img.setAttribute("class", "selected");
+	} else {
+		img.setAttribute("class", "");
+		anySelected = document.querySelectorAll(".selected").length>0;
+		if (anySelected == false)
+			divHeight -= 4;
+
+	}
+
+	moveToggleImg(options_link, divHeight);
+}
+
+function toggleVisibility(element) {
+	var divHeight;
+    if(element.style.display == 'block') {
+    	divHeight = 0 - element.clientHeight;
+    	element.style.display = 'none';
+    } else { 
+    	element.style.display = 'block';
+    	divHeight = element.clientHeight;
+    }
+    return divHeight;
+}
+
+function moveToggleImg(element, height) {
+	var curTop = (element.style.top == "" ? 0 : parseInt(element.style.top));
+	element.style.top = curTop + height;   
+}
+
+function changeImg(img, loc) {
+	img.src = loc;
+}
+
+var currentCmd = 0;
+function keyPressed() {
+	document.querySelector("#command_field").onkeyup=function(e) {
+		if (!e) e = window.event;
+		var keyCode = e.which || e.keyCode;
+		if (keyCode == 38 || keyCode == 40 || keyCode == 13 || keyCode == 27) {
+			var cmdHistoryList = document.querySelectorAll(".command");
+			switch (keyCode) {
+			case 13:
+				// press enter 
+
+				if (getCommand().toLowerCase()=="clear") {
+					clearHistory();
+				} else {
+					currentCmd = cmdHistoryList.length + 1;
+					document.querySelector("#submit").click();
+				}
+				break;
+				
+			case 27:
+				//press escape
+				currentCmd = cmdHistoryList.length;
+				document.querySelector("#command_field").value = "";
+				break;
+	
+			case 38:
+				// press arrow up	
+				if (currentCmd != 0)
+					currentCmd -= 1;
+				if (cmdHistoryList.length != 0) 
+					document.querySelector("#command_field").value = cmdHistoryList[currentCmd].innerHTML;
+				break;
+			case 40:
+				// press arrow down
+				var cmdText = "";
+				currentCmd = (currentCmd == cmdHistoryList.length) ? currentCmd : currentCmd + 1;
+				if (currentCmd < cmdHistoryList.length) 
+					cmdText = cmdHistoryList[currentCmd].innerHTML;
+				
+				document.querySelector("#command_field").value = cmdText;
+				break;
+			}
+		}
+	}
+}
+
+function saveToFile() {
+	var commands = document.querySelectorAll(".command");
+	var responses = document.querySelectorAll(".response");
+	var textToWrite = "";
+	for (var i = 0; i < commands.length; i++) {
+		textToWrite += "> " + commands[i].innerHTML + "\r\n";
+		textToWrite += prettyResponse(responses[i].firstChild.innerHTML);
+	}
+	
+    var ie = navigator.userAgent.match(/MSIE\s([\d.]+)/);
+    var ie11 = navigator.userAgent.match(/Trident\/7.0/) && navigator.userAgent.match(/rv:11/);
+    var ieVer=(ie ? ie[1] : (ie11 ? 11 : -1));
+    
+//    if (ie && ieVer<10) {
+//        console.log("No blobs on IE ver<10");
+//        return;
+//    }
+
+	var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'});
+	var fileName = "AAFcommands.log";
+	
+	if (ieVer >= 10) {
+//		window.navigator.msSaveBlob(textFileAsBlob, fileName);
+		window.navigator.msSaveOrOpenBlob(textFileAsBlob, fileName); 
+	} else {
+		var downloadLink = document.createElement("a");
+		downloadLink.download = fileName;
+		downloadLink.innerHTML = "Download File";
+		if (window.webkitURL != null) {
+			// Chrome allows the link to be clicked
+			// without actually adding it to the DOM.
+			downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
+		} else {
+			// Firefox requires the link to be added to the DOM
+			// before it can be clicked.
+			downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
+			downloadLink.onclick = destroyClickedElement;
+			downloadLink.style.display = "none";
+			document.body.appendChild(downloadLink);
+		}
+	
+		downloadLink.click();
+	}
+}
+
+function prettyResponse(response) {
+	var lines = response.split('\n');
+	var cleanResponse = "";
+	for (var i=0; i < lines.length; i++) {
+		cleanResponse += lines[i] + "\r\n";
+	}
+	cleanResponse = cleanResponse.replace(/(&lt;)/g,"<").replace(/(&gt;)/g,">");
+	return cleanResponse;
+}
+
+function destroyClickedElement(event){
+	document.body.removeChild(event.target);
+}
+
+function fakePlaceholder() {
+	document.querySelector("#command_field").setAttribute("value", "Type your AAFCLI commands here");
+}
+
+function maximizeConsole(img) {
+	var footer = document.querySelector("#footer");
+	var console_area = document.querySelector("#console_area");
+	var content = document.querySelector("#content");
+	var input_area = document.querySelector("#input_area");
+	var help_msg = document.querySelector("#help_msg");
+	var console_space = document.documentElement.clientHeight;
+	console_space -= input_area.outerHeight;
+	console_space -= help_msg.outerHeight;
+    var height = getStyle(console_area,'paddingTop') + getStyle(console_area,'paddingBottom');
+	console_space -= height;
+	
+	
+	if (content.getAttribute("class") != "maximized") {
+		content.setAttribute("class", "maximized");
+		footer.style.display="none";
+		console_area.style.resize="none";
+		console_area.style.height=console_space.toString()+"px";
+	} else {
+		content.removeAttribute("class");
+		footer.style.display="";
+		console_area.style.resize="vertical";
+		console_area.style.height="300px";
+	}
+	selectOption(img,0);
+}
diff --git a/authz-gui/theme/favicon.ico b/authz-gui/theme/favicon.ico
new file mode 100644
index 0000000..3aea272
--- /dev/null
+++ b/authz-gui/theme/favicon.ico
Binary files differ
diff --git a/authz-gui/theme/options_down.png b/authz-gui/theme/options_down.png
new file mode 100644
index 0000000..a20e826
--- /dev/null
+++ b/authz-gui/theme/options_down.png
Binary files differ
diff --git a/authz-gui/theme/options_up.png b/authz-gui/theme/options_up.png
new file mode 100644
index 0000000..7414dab
--- /dev/null
+++ b/authz-gui/theme/options_up.png
Binary files differ
diff --git a/authz-gui/theme/t_bubbles.jpg b/authz-gui/theme/t_bubbles.jpg
new file mode 100644
index 0000000..ecff55e
--- /dev/null
+++ b/authz-gui/theme/t_bubbles.jpg
Binary files differ
diff --git a/authz-gw/pom.xml b/authz-gw/pom.xml
new file mode 100644
index 0000000..6b085f7
--- /dev/null
+++ b/authz-gw/pom.xml
@@ -0,0 +1,185 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-gw</artifactId>

+	<name>Authz Gate/Wall</name>

+	<description>GW API</description>

+		<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>true</maven.test.failure.ignore>

+		<project.swmVersion>30</project.swmVersion>

+			<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+	</properties>

+		

+	<dependencies>

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-core</artifactId>

+         

+            <exclusions>

+			  <exclusion> 

+					<groupId>javax.servlet</groupId>

+       			<artifactId>servlet-api</artifactId>

+       			       		   </exclusion>

+		    </exclusions> 

+        </dependency>

+	    

+		<dependency> 

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+		</dependency>

+

+

+		

+	</dependencies>

+	

+	<build>

+		<plugins>

+			<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->

+				<plugin>

+					<groupId>org.codehaus.mojo</groupId>

+					<artifactId>jaxb2-maven-plugin</artifactId>

+				</plugin>

+	            <plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-jar-plugin</artifactId>

+					<configuration>

+	                	<includes>

+	                		<include>**/*.class</include>

+	                	</includes>

+					</configuration>

+					<version>2.3.1</version>

+				</plugin>

+			    

+			    <plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<configuration>

+						<skip>true</skip>

+					</configuration>

+			    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin> 

+		

+			</plugins>

+	</build>

+<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+</project>

diff --git a/authz-gw/src/main/config/authGW.props b/authz-gw/src/main/config/authGW.props
new file mode 100644
index 0000000..294db35
--- /dev/null
+++ b/authz-gw/src/main/config/authGW.props
@@ -0,0 +1,33 @@
+##
+## AUTHZ GateWall (authz-gw) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+AFT_ENV_CONTEXT=_ENV_CONTEXT_
+
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+
+##DME2 related parameters
+DMEServiceName=service=com.att.authz.authz-gw/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_GW_PORT_RANGE_
+
+# Turn on both AAF TAF & LUR 2.0                                                
+aaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+
+# CSP
+csp_domain=PROD
+
+# GUI Login Page
+cadi_loginpage_url=https://DME2RESOLVE/service=com.att.authz.authz-gui/version=_MAJOR_VER_._MINOR_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_/login
+
+
diff --git a/authz-gw/src/main/config/log4j.properties b/authz-gw/src/main/config/log4j.properties
new file mode 100644
index 0000000..fb5f22c
--- /dev/null
+++ b/authz-gw/src/main/config/log4j.properties
@@ -0,0 +1,79 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}

+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.INIT.layout.ConversionPattern=%d %p [%c] %m %n

+

+log4j.appender.GW=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.GW.File=_LOG_DIR_/${LOG4J_FILENAME_gw}

+log4j.appender.GW.DatePattern='.'yyyy-MM-dd

+#log4j.appender.GW.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.GW.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.GW.layout=org.apache.log4j.PatternLayout 

+log4j.appender.GW.layout.ConversionPattern=%d %p [%c] %m %n

+

+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}

+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.GW.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.GW.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.AUDIT.layout.ConversionPattern=%d %p [%c] %m %n

+

+log4j.appender.stdout=org.apache.log4j.ConsoleAppender

+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN

+log4j.logger.org.apache=WARN,INIT

+log4j.logger.dme2=WARN,INIT

+log4j.logger.init=INFO,INIT

+log4j.logger.gw=_LOG4J_LEVEL_,GW

+log4j.logger.audit=INFO,AUDIT

+

diff --git a/authz-gw/src/main/config/lrm-authz-gw.xml b/authz-gw/src/main/config/lrm-authz-gw.xml
new file mode 100644
index 0000000..f48470d
--- /dev/null
+++ b/authz-gw/src/main/config/lrm-authz-gw.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">

+    <ns2:ManagedResource>

+        <ResourceDescriptor>

+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>

+            <ResourceVersion>

+                <Major>_MAJOR_VER_</Major>

+                <Minor>_MINOR_VER_</Minor>

+                <Patch>_PATCH_VER_</Patch>                

+            </ResourceVersion>

+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>

+        </ResourceDescriptor>

+        <ResourceType>Java</ResourceType>

+        <ResourcePath>com.att.authz.gw.GwAPI</ResourcePath>

+        <ResourceProps>

+            <Tag>process.workdir</Tag>

+            <Value>_ROOT_DIR_</Value>

+        </ResourceProps>    	       

+        <ResourceProps>

+            <Tag>jvm.version</Tag>

+            <Value>1.8</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.args</Tag>

+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.classpath</Tag>

+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.min</Tag>

+            <Value>512m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.max</Tag>

+            <Value>2048m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>start.class</Tag>

+            <Value>com.att.authz.gw.GwAPI</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stdout.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stderr.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>

+        </ResourceProps>

+        <ResourceOSID>aft</ResourceOSID>

+        <ResourceStartType>AUTO</ResourceStartType>

+        <ResourceStartPriority>4</ResourceStartPriority>

+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>

+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        

+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>

+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>

+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>

+    </ns2:ManagedResource>

+</ns2:ManagedResourceList>

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwAPI.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwAPI.java
new file mode 100644
index 0000000..5872e7d
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwAPI.java
@@ -0,0 +1,248 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw;

+

+import java.net.HttpURLConnection;

+import java.util.ArrayList;

+import java.util.EnumSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Properties;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.gw.api.API_AAFAccess;

+import org.onap.aaf.authz.gw.api.API_Api;

+import org.onap.aaf.authz.gw.api.API_Find;

+import org.onap.aaf.authz.gw.api.API_Proxy;

+import org.onap.aaf.authz.gw.api.API_TGuard;

+import org.onap.aaf.authz.gw.facade.GwFacade_1_0;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.server.AbsServer;

+import org.onap.aaf.cache.Cache;

+import org.onap.aaf.cache.Cache.Dated;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.api.DME2Exception;

+

+import com.att.aft.dme2.api.DME2Manager;

+import com.att.aft.dme2.api.DME2Server;

+import com.att.aft.dme2.api.DME2ServerProperties;

+import com.att.aft.dme2.api.DME2ServiceHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.util.DME2ServletHolder;

+import org.onap.aaf.cadi.CadiException;

+//import org.onap.aaf.cadi.PropAccess;

+import org.onap.aaf.cadi.aaf.v2_0.AAFAuthn;

+import org.onap.aaf.cadi.aaf.v2_0.AAFLurPerm;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.APIException;

+

+public class GwAPI extends AbsServer {

+	private static final String USER_PERMS = "userPerms";

+	private GwFacade_1_0 facade; // this is the default Facade

+	private GwFacade_1_0 facade_1_0_XML;

+	public Map<String, Dated> cacheUser;

+	public final String aafurl;

+	public final AAFAuthn<HttpURLConnection> aafAuthn;

+	public final AAFLurPerm aafLurPerm;

+	public DME2Manager dme2Man;

+

+	

+	/**

+	 * Construct AuthzAPI with all the Context Supporting Routes that Authz needs

+	 * 

+	 * @param env

+	 * @param si 

+	 * @param dm 

+	 * @param decryptor 

+	 * @throws APIException 

+	 */

+	public GwAPI(AuthzEnv env) throws Exception {

+		super(env,"AAF GW");

+		aafurl = env.getProperty(Config.AAF_URL); 

+

+		// Setup Logging

+		//env.setLog4JNames("log4j.properties","authz","gw","audit","init","trace");

+

+		aafLurPerm = aafCon.newLur();

+		// Note: If you need both Authn and Authz construct the following:

+		aafAuthn = aafCon.newAuthn(aafLurPerm);

+

+		// Initialize Facade for all uses

+		//AuthzTrans trans = env.newTrans();

+

+	//	facade = GwFacadeFactory.v1_0(env,trans,Data.TYPE.JSON);   // Default Facade

+	//	facade_1_0_XML = GwFacadeFactory.v1_0(env,trans,Data.TYPE.XML);

+

+		synchronized(env) {

+			if(cacheUser == null) {

+				cacheUser = Cache.obtain(USER_PERMS);

+				//Cache.startCleansing(env, USER_PERMS);

+				Cache.addShutdownHook(); // Setup Shutdown Hook to close cache

+			}

+		}

+		

+		////////////////////////////////////////////////////////////////////////////

+		// Time Critical

+		//  These will always be evaluated first

+		////////////////////////////////////////////////////////////////////////

+		API_AAFAccess.init(this,facade);

+		API_Find.init(this, facade);

+		API_TGuard.init(this, facade);

+		API_Proxy.init(this, facade);

+		

+		////////////////////////////////////////////////////////////////////////

+		// Management APIs

+		////////////////////////////////////////////////////////////////////////

+		// There are several APIs around each concept, and it gets a bit too

+		// long in this class to create.  The initialization of these Management

+		// APIs have therefore been pushed to StandAlone Classes with static

+		// init functions

+		API_Api.init(this, facade);

+

+		////////////////////////////////////////////////////////////////////////

+		// Default Function

+		////////////////////////////////////////////////////////////////////////

+		API_AAFAccess.initDefault(this,facade);

+

+	}

+	

+	/**

+	 * Setup XML and JSON implementations for each supported Version type

+	 * 

+	 * We do this by taking the Code passed in and creating clones of these with the appropriate Facades and properties

+	 * to do Versions and Content switches

+	 * 

+	 */

+	public void route(HttpMethods meth, String path, API api, GwCode code) throws Exception {

+		String version = "1.0";

+		// Get Correct API Class from Mapper

+		Class<?> respCls = facade.mapper().getClass(api); 

+		if(respCls==null) throw new Exception("Unknown class associated with " + api.getClass().getName() + ' ' + api.name());

+		// setup Application API HTML ContentTypes for JSON and Route

+		String application = applicationJSON(respCls, version);

+		//route(env,meth,path,code,application,"application/json;version="+version,"*/*");

+

+		// setup Application API HTML ContentTypes for XML and Route

+		application = applicationXML(respCls, version);

+		//route(env,meth,path,code.clone(facade_1_0_XML,false),application,"text/xml;version="+version);

+		

+		// Add other Supported APIs here as created

+	}

+	

+	public void routeAll(HttpMethods meth, String path, API api, GwCode code) throws Exception {

+		//route(env,meth,path,code,""); // this will always match

+	}

+

+

+	/**

+	 * Start up AuthzAPI as DME2 Service

+	 * @param env

+	 * @param props

+	 * @throws DME2Exception

+	 * @throws CadiException 

+	 */

+	public void startDME2(Properties props) throws DME2Exception, CadiException {

+		

+		dme2Man = new DME2Manager("GatewayDME2Manager",props);

+

+        DME2ServiceHolder svcHolder;

+        List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();

+        svcHolder = new DME2ServiceHolder();

+        String serviceName = env.getProperty("DMEServiceName",null);

+    	if(serviceName!=null) {

+	    	svcHolder.setServiceURI(serviceName);

+	        svcHolder.setManager(dme2Man);

+	        svcHolder.setContext("/");

+	        

+	        

+	        

+	        DME2ServletHolder srvHolder = new DME2ServletHolder(this, new String[] {"/dme2","/api"});

+	        srvHolder.setContextPath("/*");

+	        slist.add(srvHolder);

+	        

+	        EnumSet<RequestDispatcherType> edlist = EnumSet.of(

+	        		RequestDispatcherType.REQUEST,

+	        		RequestDispatcherType.FORWARD,

+	        		RequestDispatcherType.ASYNC

+	        		);

+

+	        ///////////////////////

+	        // Apply Filters

+	        ///////////////////////

+	        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();

+	        

+	        // Leave Login page un secured

+	       // AuthzTransOnlyFilter atof = new AuthzTransOnlyFilter(env);

+	      //  flist.add(new DME2FilterHolder(atof,"/login", edlist));

+

+	        // Secure all other interactions with AuthzTransFilter

+//	        flist.add(new DME2FilterHolder(

+//	        		new AuthzTransFilter(env, aafCon, new AAFTrustChecker(

+//	    	        		env.getProperty(Config.CADI_TRUST_PROP, Config.CADI_USER_CHAIN),

+//	    	        		Define.ROOT_NS + ".mechid|"+Define.ROOT_COMPANY+"|trust"

+//	        			)),

+//	        		"/*", edlist));

+//	        

+

+	        svcHolder.setFilters(flist);

+	        svcHolder.setServletHolders(slist);

+	        

+	        DME2Server dme2svr = dme2Man.getServer();

+//	        dme2svr.setGracefulShutdownTimeMs(1000);

+	

+	       // env.init().log("Starting GW Jetty/DME2 server...");

+	        dme2svr.start();

+	        DME2ServerProperties dsprops = dme2svr.getServerProperties();

+	        try {

+//	        	if(env.getProperty("NO_REGISTER",null)!=null)

+	        	dme2Man.bindService(svcHolder);

+//	        	env.init().log("DME2 is available as HTTP"+(dsprops.isSslEnable()?"/S":""),"on port:",dsprops.getPort());

+

+	            while(true) { // Per DME2 Examples...

+	            	Thread.sleep(5000);

+	            }

+	        } catch(InterruptedException e) {

+	           // env.init().log("AAF Jetty Server interrupted!");

+	        } catch(Exception e) { // Error binding service doesn't seem to stop DME2 or Process

+	         //   env.init().log(e,"DME2 Initialization Error");

+	        	dme2svr.stop();

+	        	System.exit(1);

+	        }

+    	} else {

+    		//env.init().log("Properties must contain DMEServiceName");

+    	}

+	}

+

+	public static void main(String[] args) {

+		setup(GwAPI.class,"authGW.props");

+	}

+

+//	public void route(PropAccess env, HttpMethods get, String string, GwCode gwCode, String string2, String string3,

+//			String string4) {

+//		// TODO Auto-generated method stub

+//		

+//	}

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwCode.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwCode.java
new file mode 100644
index 0000000..a9e6eb2
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/GwCode.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.cssa.rserv.HttpCode;

+

+public abstract class GwCode extends HttpCode<AuthzTrans, GwFacade> implements Cloneable {

+	public boolean useJSON;

+

+	public GwCode(GwFacade facade, String description, boolean useJSON, String ... roles) {

+		super(facade, description, roles);

+		this.useJSON = useJSON;

+	}

+	

+	public <D extends GwCode> D clone(GwFacade facade, boolean useJSON) throws Exception {

+		@SuppressWarnings("unchecked")

+		D d = (D)clone();

+		d.useJSON = useJSON;

+		d.context = facade;

+		return d;

+	}

+	

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_AAFAccess.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_AAFAccess.java
new file mode 100644
index 0000000..202ec58
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_AAFAccess.java
@@ -0,0 +1,363 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.api;

+

+import java.io.IOException;

+import java.net.ConnectException;

+import java.net.MalformedURLException;

+import java.net.URI;

+import java.security.Principal;

+

+import javax.servlet.ServletOutputStream;

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.GwAPI;

+import org.onap.aaf.authz.gw.GwCode;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cache.Cache.Dated;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.Locator;

+import org.onap.aaf.cadi.Locator.Item;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.aaf.AAFPermission;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.dme2.DME2Locator;

+import org.onap.aaf.cadi.principal.BasicPrincipal;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+

+public class API_AAFAccess {

+	private static final String AUTHZ_DME2_GUI = "com.att.authz.authz-gui";

+	static final String AFT_ENVIRONMENT="AFT_ENVIRONMENT";

+	static final String AFT_ENV_CONTEXT="AFT_ENV_CONTEXT";

+	static final String AFTUAT="AFTUAT";

+	

+	private static final String PROD = "PROD";

+	private static final String IST = "IST"; // main NONPROD system

+	private static final String PERF = "PERF";

+	private static final String TEST = "TEST";

+	private static final String DEV = "DEV";

+	

+//	private static String service, version, envContext; 

+	private static String routeOffer;

+

+	private static final String GET_PERMS_BY_USER = "Get Perms by User";

+	private static final String USER_HAS_PERM ="User Has Perm";

+//	private static final String USER_IN_ROLE ="User Has Role";

+	private static final String BASIC_AUTH ="AAF Basic Auth";

+	

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param gwAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		String aftenv = gwAPI.env.getProperty(AFT_ENVIRONMENT);

+		if(aftenv==null) throw new Exception(AFT_ENVIRONMENT + " must be set");

+		

+		int equals, count=0;

+		for(int slash = gwAPI.aafurl.indexOf('/');slash>0;++count) {

+			equals = gwAPI.aafurl.indexOf('=',slash)+1;

+			slash = gwAPI.aafurl.indexOf('/',slash+1);

+			switch(count) {

+				case 2:

+//					service = gwAPI.aafurl.substring(equals, slash);

+					break;

+				case 3:

+//					version = gwAPI.aafurl.substring(equals, slash);

+					break;

+				case 4:

+//					envContext = gwAPI.aafurl.substring(equals, slash);

+					break;

+				case 5:

+					routeOffer = gwAPI.aafurl.substring(equals);

+					break;

+			}

+		}

+		if(count<6) throw new MalformedURLException(gwAPI.aafurl);

+		

+		gwAPI.route(HttpMethods.GET,"/authz/perms/user/:user",API.VOID,new GwCode(facade,GET_PERMS_BY_USER, true) {

+			@Override

+			public void handle(final AuthzTrans trans, final HttpServletRequest req, final HttpServletResponse resp) throws Exception {

+				TimeTaken tt = trans.start(GET_PERMS_BY_USER, Env.SUB);

+				try {

+					final String accept = req.getHeader("ACCEPT");

+					final String user = pathParam(req,":user");

+					if(!user.contains("@")) {

+						context.error(trans,resp,Result.ERR_BadData,"User [%s] must be fully qualified with domain",user);

+						return;

+					}

+					String key = trans.user() + user + (accept!=null&&accept.contains("xml")?"-xml":"-json");

+					TimeTaken tt2 = trans.start("Cache Lookup",Env.SUB);

+					Dated d;

+					try {

+						d = gwAPI.cacheUser.get(key);

+					} finally {

+						tt2.done();

+					}

+					

+					if(d==null || d.data.isEmpty()) {

+						tt2 = trans.start("AAF Service Call",Env.REMOTE);

+						try {

+							gwAPI.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {

+								@Override

+								public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {

+									Future<String> fp = client.read("/authz/perms/user/"+user,accept);

+									if(fp.get(5000)) {

+										gwAPI.cacheUser.put(key, new Dated(new User(fp.code(),fp.body())));

+										resp.setStatus(HttpStatus.OK_200);

+										ServletOutputStream sos;

+										try {

+											sos = resp.getOutputStream();

+											sos.print(fp.value);

+										} catch (IOException e) {

+											throw new CadiException(e);

+										}

+									} else {

+										gwAPI.cacheUser.put(key, new Dated(new User(fp.code(),fp.body())));

+										context.error(trans,resp,fp.code(),fp.body());

+									}

+									return null;

+								}

+							});

+						} finally {

+							tt2.done();

+						}

+					} else {

+						User u = (User)d.data.get(0);

+						resp.setStatus(u.code);

+						ServletOutputStream sos = resp.getOutputStream();

+						sos.print(u.resp);

+					}

+				} finally {

+					tt.done();

+				}

+			}

+		});

+

+		gwAPI.route(gwAPI.env,HttpMethods.GET,"/authn/basicAuth",new GwCode(facade,BASIC_AUTH, true) {

+			@Override

+			public void handle(final AuthzTrans trans, final HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Principal p = trans.getUserPrincipal();

+				if(p == null) {

+					trans.error().log("Transaction not Authenticated... no Principal");

+					resp.setStatus(HttpStatus.FORBIDDEN_403);

+				} else if (p instanceof BasicPrincipal) {

+					// the idea is that if call is made with this credential, and it's a BasicPrincipal, it's ok

+					// otherwise, it wouldn't have gotten here.

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					trans.checkpoint("Basic Auth Check Failed: This wasn't a Basic Auth Trans");

+					// For Auth Security questions, we don't give any info to client on why failed

+					resp.setStatus(HttpStatus.FORBIDDEN_403);

+				}

+			}

+		},"text/plain","*/*","*");

+

+		/**

+		 * Query User Has Perm

+		 */

+		gwAPI.route(HttpMethods.GET,"/ask/:user/has/:type/:instance/:action",API.VOID,new GwCode(facade,USER_HAS_PERM, true) {

+			@Override

+			public void handle(final AuthzTrans trans, final HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				try {

+					resp.getOutputStream().print(

+							gwAPI.aafLurPerm.fish(pathParam(req,":user"), new AAFPermission(

+								pathParam(req,":type"),

+								pathParam(req,":instance"),

+								pathParam(req,":action"))));

+					resp.setStatus(HttpStatus.OK_200);

+				} catch(Exception e) {

+					context.error(trans, resp, Result.ERR_General, e.getMessage());

+				}

+			}

+		});

+

+		if(AFTUAT.equals(aftenv)) {

+			gwAPI.route(HttpMethods.GET,"/ist/aaf/:version/:path*",API.VOID ,new GwCode(facade,"Access UAT GUI for AAF", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					try{

+						redirect(trans, req, resp, context, 

+								new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, pathParam(req,":version"), IST, routeOffer), 

+								pathParam(req,":path"));

+					} catch (LocatorException e) {

+						context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+					} catch (Exception e) {

+						context.error(trans, resp, Result.ERR_General, e.getMessage());

+					}

+				}

+			});

+

+			gwAPI.route(HttpMethods.GET,"/test/aaf/:version/:path*",API.VOID ,new GwCode(facade,"Access TEST GUI for AAF", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					try{

+						redirect(trans, req, resp, context, 

+								new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, pathParam(req,":version"), TEST, routeOffer), 

+								pathParam(req,":path"));

+					} catch (LocatorException e) {

+						context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+					} catch (Exception e) {

+						context.error(trans, resp, Result.ERR_General, e.getMessage());

+					}

+				}

+			});

+

+			gwAPI.route(HttpMethods.GET,"/perf/aaf/:version/:path*",API.VOID ,new GwCode(facade,"Access PERF GUI for AAF", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					try{

+						redirect(trans, req, resp, context, 

+								new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, pathParam(req,":version"), PERF, routeOffer), 

+								pathParam(req,":path"));

+					} catch (LocatorException e) {

+						context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+					} catch (Exception e) {

+						context.error(trans, resp, Result.ERR_General, e.getMessage());

+					}

+				}

+			});

+

+			gwAPI.route(HttpMethods.GET,"/dev/aaf/:version/:path*",API.VOID,new GwCode(facade,"Access DEV GUI for AAF", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					try {

+						redirect(trans, req, resp, context, 

+								new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, pathParam(req,":version"), DEV, routeOffer), 

+								pathParam(req,":path"));

+					} catch (LocatorException e) {

+						context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+					} catch (Exception e) {

+						context.error(trans, resp, Result.ERR_General, e.getMessage());

+					}

+				}

+			});

+		} else {

+			gwAPI.route(HttpMethods.GET,"/aaf/:version/:path*",API.VOID,new GwCode(facade,"Access PROD GUI for AAF", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					try {

+						redirect(trans, req, resp, context, 

+								new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, pathParam(req,":version"), PROD, routeOffer), 

+								pathParam(req,":path"));

+					} catch (LocatorException e) {

+						context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+					} catch (Exception e) {

+						context.error(trans, resp, Result.ERR_General, e.getMessage());

+					}

+				}

+			});

+		}

+		

+	}

+	

+	public static void initDefault(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		String aftenv = gwAPI.env.getProperty(AFT_ENVIRONMENT);

+		if(aftenv==null) throw new Exception(AFT_ENVIRONMENT + " must be set");

+	

+		String aftctx = gwAPI.env.getProperty(AFT_ENV_CONTEXT);

+		if(aftctx==null) throw new Exception(AFT_ENV_CONTEXT + " must be set");

+

+		/**

+		 * "login" url

+		 */

+		gwAPI.route(HttpMethods.GET,"/login",API.VOID,new GwCode(facade,"Access " + aftctx + " GUI for AAF", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				try {

+					redirect(trans, req, resp, context, 

+							new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, "2.0", aftctx, routeOffer), 

+							"login");

+				} catch (LocatorException e) {

+					context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+				} catch (Exception e) {

+					context.error(trans, resp, Result.ERR_General, e.getMessage());

+				}

+			}

+		});

+

+		/**

+		 * Default URL

+		 */

+		gwAPI.route(HttpMethods.GET,"/",API.VOID,new GwCode(facade,"Access " + aftctx + " GUI for AAF", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				try {

+					redirect(trans, req, resp, context, 

+							new DME2Locator(gwAPI.env, gwAPI.dme2Man, AUTHZ_DME2_GUI, "2.0", aftctx, routeOffer), 

+							"gui/home");

+				} catch (LocatorException e) {

+					context.error(trans, resp, Result.ERR_BadData, e.getMessage());

+				} catch (Exception e) {

+					context.error(trans, resp, Result.ERR_General, e.getMessage());

+				}

+			}

+		});

+	}

+

+	private static void redirect(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, GwFacade context, Locator loc, String path) throws IOException {

+		try {

+			if(loc.hasItems()) {

+				Item item = loc.best();

+				URI uri = (URI) loc.get(item);

+				StringBuilder redirectURL = new StringBuilder(uri.toString()); 

+				redirectURL.append('/');

+				redirectURL.append(path);

+				String str = req.getQueryString();

+				if(str!=null) {

+					redirectURL.append('?');

+					redirectURL.append(str);

+				}

+				trans.info().log("Redirect to",redirectURL);

+				resp.sendRedirect(redirectURL.toString());

+			} else {

+				context.error(trans, resp, Result.err(Result.ERR_NotFound,"%s is not valid",req.getPathInfo()));

+			}

+		} catch (LocatorException e) {

+			context.error(trans, resp, Result.err(Result.ERR_NotFound,"No DME2 Endpoints found for %s",req.getPathInfo()));

+		}

+	}

+

+	private static class User {

+		public final int code;

+		public final String resp;

+		

+		public User(int code, String resp) {

+			this.code = code;

+			this.resp = resp;

+		}

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Api.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Api.java
new file mode 100644
index 0000000..0a828f9
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Api.java
@@ -0,0 +1,99 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.GwAPI;

+import org.onap.aaf.authz.gw.GwCode;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.Symm;

+

+/**

+ * API Apis

+ *

+ */

+public class API_Api {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param gwAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		////////

+		// Overall APIs

+		///////

+		gwAPI.route(HttpMethods.GET,"/api",API.VOID,new GwCode(facade,"Document API", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getAPI(trans,resp,gwAPI);

+				switch(r.status) {

+				case OK:

+					resp.setStatus(HttpStatus.OK_200);

+					break;

+				default:

+					context.error(trans,resp,r);

+			}

+

+			}

+		});

+

+		////////

+		// Overall Examples

+		///////

+		gwAPI.route(HttpMethods.GET,"/api/example/*",API.VOID,new GwCode(facade,"Document API", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String pathInfo = req.getPathInfo();

+				int question = pathInfo.lastIndexOf('?');

+				

+				pathInfo = pathInfo.substring(13, question<0?pathInfo.length():question);// IMPORTANT, this is size of "/api/example/"

+				String nameOrContextType=Symm.base64noSplit.decode(pathInfo);

+//				String param = req.getParameter("optional");

+				Result<Void> r = context.getAPIExample(trans,resp,nameOrContextType,

+						question>=0 && "optional=true".equalsIgnoreCase(req.getPathInfo().substring(question+1))

+						);

+				switch(r.status) {

+				case OK:

+					resp.setStatus(HttpStatus.OK_200);

+					break;

+				default:

+					context.error(trans,resp,r);

+			}

+

+			}

+		});

+

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Find.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Find.java
new file mode 100644
index 0000000..63595f0
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Find.java
@@ -0,0 +1,87 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.api;

+

+import java.net.URI;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.GwAPI;

+import org.onap.aaf.authz.gw.GwCode;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import org.onap.aaf.cadi.Locator;

+import org.onap.aaf.cadi.Locator.Item;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.dme2.DME2Locator;

+

+/**

+ * API Apis.. using Redirect for mechanism

+ * 

+ *

+ */

+public class API_Find {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param gwAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		////////

+		// Overall APIs

+		///////

+		gwAPI.route(HttpMethods.GET,"/dme2/:service/:version/:envContext/:routeOffer/:path*",API.VOID,new GwCode(facade,"Document API", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				//TODO cache this...

+				try {

+					Locator loc = new DME2Locator(gwAPI.env, gwAPI.dme2Man, 

+						pathParam(req,":service"),

+						pathParam(req,":version"),

+						pathParam(req,":envContext"),

+						pathParam(req,":routeOffer")

+						);

+					if(loc.hasItems()) {

+						Item item = loc.best();

+						URI uri = (URI) loc.get(item);

+						String redirectURL = uri.toString() + '/' + pathParam(req,":path");

+						trans.warn().log("Redirect to",redirectURL);

+						resp.sendRedirect(redirectURL);

+					} else {

+						context.error(trans, resp, Result.err(Result.ERR_NotFound,"%s is not valid",req.getPathInfo()));

+					}

+				} catch (LocatorException e) {

+					context.error(trans, resp, Result.err(Result.ERR_NotFound,"No DME2 Endpoints found for %s",req.getPathInfo()));

+				}

+			}

+		});

+

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Proxy.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Proxy.java
new file mode 100644
index 0000000..90d754e
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_Proxy.java
@@ -0,0 +1,156 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.api;

+

+import java.net.ConnectException;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.GwAPI;

+import org.onap.aaf.authz.gw.GwCode;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.client.Future;

+import org.onap.aaf.cadi.client.Rcli;

+import org.onap.aaf.cadi.client.Retryable;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+

+/**

+ * API Apis.. using Redirect for mechanism

+ * 

+ *

+ */

+public class API_Proxy {

+

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param gwAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		

+		String aafurl = gwAPI.env.getProperty(Config.AAF_URL);

+		if(aafurl==null) {

+		} else {

+

+			////////

+			// Transferring APIs

+			///////

+			gwAPI.routeAll(HttpMethods.GET,"/proxy/:path*",API.VOID,new GwCode(facade,"Proxy GET", true) {

+				@Override

+				public void handle(final AuthzTrans trans, final HttpServletRequest req, final HttpServletResponse resp) throws Exception {

+					TimeTaken tt = trans.start("Forward to AAF Service", Env.REMOTE);

+					try {

+						gwAPI.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {

+							@Override

+							public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {

+								Future<Void> ft = client.transfer(req,resp,pathParam(req, ":path"),HttpStatus.OK_200);

+								ft.get(10000); // Covers return codes and err messages

+								return null;

+							}

+						});

+					

+					} catch (CadiException | APIException e) {

+						trans.error().log(e);

+					} finally {

+						tt.done();

+					}

+				}

+			});

+			

+			gwAPI.routeAll(HttpMethods.POST,"/proxy/:path*",API.VOID,new GwCode(facade,"Proxy POST", true) {

+				@Override

+				public void handle(final AuthzTrans trans, final HttpServletRequest req, final HttpServletResponse resp) throws Exception {

+					TimeTaken tt = trans.start("Forward to AAF Service", Env.REMOTE);

+					try {

+						gwAPI.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {

+							@Override

+							public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {

+								Future<Void> ft = client.transfer(req,resp,pathParam(req, ":path"),HttpStatus.CREATED_201);

+								ft.get(10000); // Covers return codes and err messages

+								return null;

+							}

+						});

+					} catch (CadiException | APIException e) {

+						trans.error().log(e);

+					} finally {

+						tt.done();

+					}

+				}

+			});

+			

+			gwAPI.routeAll(HttpMethods.PUT,"/proxy/:path*",API.VOID,new GwCode(facade,"Proxy PUT", true) {

+				@Override

+				public void handle(final AuthzTrans trans, final HttpServletRequest req, final HttpServletResponse resp) throws Exception {

+					TimeTaken tt = trans.start("Forward to AAF Service", Env.REMOTE);

+					try {

+						gwAPI.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {

+							@Override

+							public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {

+								Future<Void> ft = client.transfer(req,resp,pathParam(req, ":path"),HttpStatus.OK_200);

+								ft.get(10000); // Covers return codes and err messages

+								return null;

+							}

+						});

+					} catch (CadiException | APIException e) {

+						trans.error().log(e);

+					} finally {

+						tt.done();

+					}

+				}

+			});

+			

+			gwAPI.routeAll(HttpMethods.DELETE,"/proxy/:path*",API.VOID,new GwCode(facade,"Proxy DELETE", true) {

+				@Override

+				public void handle(final AuthzTrans trans, final HttpServletRequest req, final HttpServletResponse resp) throws Exception {

+					TimeTaken tt = trans.start("Forward to AAF Service", Env.REMOTE);

+					try {

+						gwAPI.clientAsUser(trans.getUserPrincipal(), new Retryable<Void>() {

+							@Override

+							public Void code(Rcli<?> client) throws CadiException, ConnectException, APIException {

+								Future<Void> ft = client.transfer(req,resp,pathParam(req, ":path"),HttpStatus.OK_200);

+								ft.get(10000); // Covers return codes and err messages

+								return null;

+							}

+						});

+					} catch (CadiException | APIException e) {

+						trans.error().log(e);

+					} finally {

+						tt.done();

+					}

+				}

+			});

+		}

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_TGuard.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_TGuard.java
new file mode 100644
index 0000000..876782f
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/api/API_TGuard.java
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.GwAPI;

+import org.onap.aaf.authz.gw.GwCode;

+import org.onap.aaf.authz.gw.facade.GwFacade;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+/**

+ * API Apis

+ *

+ */

+public class API_TGuard {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param gwAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final GwAPI gwAPI, GwFacade facade) throws Exception {

+		String aftenv = gwAPI.env.getProperty(API_AAFAccess.AFT_ENVIRONMENT);

+		if(aftenv==null) throw new Exception(API_AAFAccess.AFT_ENVIRONMENT + " must be set");

+

+		////////

+		// Do not deploy these to PROD

+		///////

+		if(API_AAFAccess.AFTUAT.equals(aftenv)) {

+			gwAPI.route(HttpMethods.GET,"/tguard/:path*",API.VOID,new GwCode(facade,"TGuard Test", true) {

+				@Override

+				public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getAPI(trans,resp,gwAPI);

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200);

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			});

+		}

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade.java
new file mode 100644
index 0000000..e5f3919
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.facade;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.RServlet;

+

+

+/**

+ *   

+ *

+ */

+public interface GwFacade {

+

+/////////////////////  STANDARD ELEMENTS //////////////////

+	/** 

+	 * @param trans

+	 * @param response

+	 * @param result

+	 */

+	void error(AuthzTrans trans, HttpServletResponse response, Result<?> result);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param response

+	 * @param status

+	 */

+	void error(AuthzTrans trans, HttpServletResponse response, int status,	String msg, String ... detail);

+

+

+	/**

+	 * 

+	 * @param trans

+	 * @param resp

+	 * @param rservlet

+	 * @return

+	 */

+	public Result<Void> getAPI(AuthzTrans trans, HttpServletResponse resp, RServlet<AuthzTrans> rservlet);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param resp

+	 * @param typeCode

+	 * @param optional

+	 * @return

+	 */

+	public abstract Result<Void> getAPIExample(AuthzTrans trans, HttpServletResponse resp, String typeCode, boolean optional);

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeFactory.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeFactory.java
new file mode 100644
index 0000000..30f9ce2
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.facade;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.mapper.Mapper_1_0;

+import org.onap.aaf.authz.gw.service.GwServiceImpl;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+import gw.v1_0.Error;

+import gw.v1_0.InRequest;

+import gw.v1_0.Out;

+

+

+public class GwFacadeFactory {

+	public static GwFacade_1_0 v1_0(AuthzEnv env, AuthzTrans trans, Data.TYPE type) throws APIException {

+		return new GwFacade_1_0(env,

+				new GwServiceImpl<

+					InRequest,

+					Out,

+					Error>(trans,new Mapper_1_0()),

+				type);  

+	}

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeImpl.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeImpl.java
new file mode 100644
index 0000000..fa61066
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacadeImpl.java
@@ -0,0 +1,258 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.facade;

+

+

+import static org.onap.aaf.authz.layer.Result.ERR_ActionNotCompleted;

+import static org.onap.aaf.authz.layer.Result.ERR_BadData;

+import static org.onap.aaf.authz.layer.Result.ERR_ConflictAlreadyExists;

+import static org.onap.aaf.authz.layer.Result.ERR_Denied;

+import static org.onap.aaf.authz.layer.Result.ERR_NotFound;

+import static org.onap.aaf.authz.layer.Result.ERR_NotImplemented;

+import static org.onap.aaf.authz.layer.Result.ERR_Policy;

+import static org.onap.aaf.authz.layer.Result.ERR_Security;

+

+import java.lang.reflect.Method;

+

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.mapper.Mapper;

+import org.onap.aaf.authz.gw.mapper.Mapper.API;

+import org.onap.aaf.authz.gw.service.GwService;

+import org.onap.aaf.authz.gw.service.GwServiceImpl;

+import org.onap.aaf.authz.layer.FacadeImpl;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.RServlet;

+import org.onap.aaf.cssa.rserv.RouteReport;

+import org.onap.aaf.cssa.rserv.doc.ApiDoc;

+

+import org.onap.aaf.cadi.aaf.client.Examples;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Data.TYPE;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.rosetta.env.RosettaDF;

+

+import gw.v1_0.Api;

+

+/**

+ * AuthzFacade

+ * 

+ * This Service Facade encapsulates the essence of the API Service can do, and provides

+ * a single created object for elements such as RosettaDF.

+ *

+ * The Responsibilities of this class are to:

+ * 1) Interact with the Service Implementation (which might be supported by various kinds of Backend Storage)

+ * 2) Validate incoming data (if applicable)

+ * 3) Convert the Service response into the right Format, and mark the Content Type

+ * 		a) In the future, we may support multiple Response Formats, aka JSON or XML, based on User Request.

+ * 4) Log Service info, warnings and exceptions as necessary

+ * 5) When asked by the API layer, this will create and write Error content to the OutputStream

+ * 

+ * Note: This Class does NOT set the HTTP Status Code.  That is up to the API layer, so that it can be 

+ * clearly coordinated with the API Documentation

+ * 

+ *

+ */

+public abstract class GwFacadeImpl<IN,OUT,ERROR> extends FacadeImpl implements GwFacade 

+	{

+	private GwService<IN,OUT,ERROR> service;

+

+	private final RosettaDF<ERROR>	 	errDF;

+	private final RosettaDF<Api>	 	apiDF;

+

+	public GwFacadeImpl(AuthzEnv env, GwService<IN,OUT,ERROR> service, Data.TYPE dataType) throws APIException {

+		this.service = service;

+		(errDF 				= env.newDataFactory(mapper().getClass(API.ERROR))).in(dataType).out(dataType);

+		(apiDF				= env.newDataFactory(Api.class)).in(dataType).out(dataType);

+	}

+	

+	public Mapper<IN,OUT,ERROR> mapper() {

+		return service.mapper();

+	}

+		

+	/* (non-Javadoc)

+	 * @see com.att.authz.facade.AuthzFacade#error(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, int)

+	 * 

+	 * Note: Conforms to AT&T TSS RESTful Error Structure

+	 */

+	@Override

+	public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {

+		String msg = result.details==null?"":result.details.trim();

+		String[] detail;

+		if(result.variables==null) {

+			detail = new String[1];

+		} else {

+			int l = result.variables.length;

+			detail=new String[l+1];

+			System.arraycopy(result.variables, 0, detail, 1, l);

+		}

+		error(trans, response, result.status,msg,detail);

+	}

+		

+	@Override

+	public void error(AuthzTrans trans, HttpServletResponse response, int status, String msg, String ... _detail) {

+	    	String[] detail = _detail;

+		if(detail.length==0) {

+		    detail=new String[1];

+		}

+		String msgId;

+		switch(status) {

+			case 202:

+			case ERR_ActionNotCompleted:

+				msgId = "SVC1202";

+				detail[0] = "Accepted, Action not complete";

+				response.setStatus(/*httpstatus=*/202);

+				break;

+

+			case 403:

+			case ERR_Policy:

+			case ERR_Security:

+			case ERR_Denied:

+				msgId = "SVC1403";

+				detail[0] = "Forbidden";

+				response.setStatus(/*httpstatus=*/403);

+				break;

+				

+			case 404:

+			case ERR_NotFound:

+				msgId = "SVC1404";

+				detail[0] = "Not Found";

+				response.setStatus(/*httpstatus=*/404);

+				break;

+

+			case 406:

+			case ERR_BadData:

+				msgId="SVC1406";

+				detail[0] = "Not Acceptable";

+				response.setStatus(/*httpstatus=*/406);

+				break;

+				

+			case 409:

+			case ERR_ConflictAlreadyExists:

+				msgId = "SVC1409";

+				detail[0] = "Conflict Already Exists";

+				response.setStatus(/*httpstatus=*/409);

+				break;

+			

+			case 501:

+			case ERR_NotImplemented:

+				msgId = "SVC1501";

+				detail[0] = "Not Implemented"; 

+				response.setStatus(/*httpstatus=*/501);

+				break;

+				

+

+			default:

+				msgId = "SVC1500";

+				detail[0] = "General Service Error";

+				response.setStatus(/*httpstatus=*/500);

+				break;

+		}

+

+		try {

+			StringBuilder holder = new StringBuilder();

+			errDF.newData(trans).load(

+				mapper().errorFromMessage(holder,msgId,msg,detail)).to(response.getOutputStream());

+			trans.checkpoint(

+					"ErrResp [" + 

+					msgId +

+					"] " +

+					holder.toString(),

+					Env.ALWAYS);

+		} catch (Exception e) {

+			trans.error().log(e,"unable to send response for",msg);

+		}

+	}

+	

+	/* (non-Javadoc)

+	 * @see com.att.authz.facade.AuthzFacade#getAPI(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse)

+	 */

+	public final static String API_REPORT = "apiReport";

+	@Override

+	public Result<Void> getAPI(AuthzTrans trans, HttpServletResponse resp, RServlet<AuthzTrans> rservlet) {

+		TimeTaken tt = trans.start(API_REPORT, Env.SUB);

+		try {

+			Api api = new Api();

+			Api.Route ar;

+			Method[] meths = GwServiceImpl.class.getDeclaredMethods();

+			for(RouteReport rr : rservlet.routeReport()) {

+				api.getRoute().add(ar = new Api.Route());

+				ar.setMeth(rr.meth.name());

+				ar.setPath(rr.path);

+				ar.setDesc(rr.desc);

+				ar.getContentType().addAll(rr.contextTypes);

+				for(Method m : meths) {

+					ApiDoc ad;

+					if((ad = m.getAnnotation(ApiDoc.class))!=null &&

+							rr.meth.equals(ad.method()) &&

+						    rr.path.equals(ad.path())) {

+						for(String param : ad.params()) {

+							ar.getParam().add(param);

+						}

+						for(String text : ad.text()) {

+							ar.getComments().add(text);

+						}

+						ar.setExpected(ad.expectedCode());

+						for(int ec : ad.errorCodes()) {

+							ar.getExplicitErr().add(ec);

+						}

+					}

+				}

+			}

+			apiDF.newData(trans).load(api).to(resp.getOutputStream());

+			setContentType(resp,apiDF.getOutType());

+			return Result.ok();

+

+		} catch (Exception e) {

+			trans.error().log(e,IN,API_REPORT);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	public final static String API_EXAMPLE = "apiExample";

+	/* (non-Javadoc)

+	 * @see com.att.authz.facade.AuthzFacade#getAPIExample(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getAPIExample(AuthzTrans trans, HttpServletResponse resp, String nameOrContentType, boolean optional) {

+		TimeTaken tt = trans.start(API_EXAMPLE, Env.SUB);

+		try {

+			String content =Examples.print(apiDF.getEnv(), nameOrContentType, optional); 

+			resp.getOutputStream().print(content);

+			setContentType(resp,content.contains("<?xml")?TYPE.XML:TYPE.JSON);

+			return Result.ok();

+		} catch (Exception e) {

+			trans.error().log(e,IN,API_EXAMPLE);

+			return Result.err(Result.ERR_NotImplemented,e.getMessage());

+		} finally {

+			tt.done();

+		}

+	}

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade_1_0.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade_1_0.java
new file mode 100644
index 0000000..188144c
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/facade/GwFacade_1_0.java
@@ -0,0 +1,40 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.facade;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.gw.service.GwService;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+import gw.v1_0.Error;

+import gw.v1_0.InRequest;

+import gw.v1_0.Out;

+

+public class GwFacade_1_0 extends GwFacadeImpl<InRequest,Out,Error>

+{

+	public GwFacade_1_0(AuthzEnv env, GwService<InRequest,Out,Error> service, Data.TYPE type) throws APIException {

+		super(env, service, type);

+	}

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper.java
new file mode 100644
index 0000000..230e1b3
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.mapper;

+

+public interface Mapper<IN,OUT,ERROR>

+{

+	public enum API{IN_REQ,OUT,ERROR,VOID};

+	public Class<?> getClass(API api);

+	public<A> A newInstance(API api);

+

+	public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, String... detail);

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper_1_0.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper_1_0.java
new file mode 100644
index 0000000..ba87631
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/mapper/Mapper_1_0.java
@@ -0,0 +1,69 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.mapper;

+

+import org.onap.aaf.cadi.util.Vars;

+

+import gw.v1_0.Error;

+import gw.v1_0.InRequest;

+import gw.v1_0.Out;

+

+public class Mapper_1_0 implements Mapper<InRequest,Out,Error> {

+	

+	@Override

+	public Class<?> getClass(API api) {

+		switch(api) {

+			case IN_REQ: return InRequest.class;

+			case OUT: return Out.class;

+			case ERROR: return Error.class;

+			case VOID: return Void.class;

+		}

+		return null;

+	}

+

+	@SuppressWarnings("unchecked")

+	@Override

+	public <A> A newInstance(API api) {

+		switch(api) {

+			case IN_REQ: return (A) new InRequest();

+			case OUT: return (A) new Out();

+			case ERROR: return (A)new Error();

+			case VOID: return null;

+		}

+		return null;

+	}

+

+	//////////////  Mapping Functions /////////////

+	@Override

+	public gw.v1_0.Error errorFromMessage(StringBuilder holder, String msgID, String text,String... var) {

+		Error err = new Error();

+		err.setMessageId(msgID);

+		// AT&T Restful Error Format requires numbers "%" placements

+		err.setText(Vars.convert(holder, text, var));

+		for(String s : var) {

+			err.getVariables().add(s);

+		}

+		return err;

+	}

+

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwService.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwService.java
new file mode 100644
index 0000000..c4f240e
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwService.java
@@ -0,0 +1,29 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.service;

+

+import org.onap.aaf.authz.gw.mapper.Mapper;

+

+public interface GwService<IN,OUT,ERROR> {

+	public Mapper<IN,OUT,ERROR> mapper();

+}

diff --git a/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwServiceImpl.java b/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwServiceImpl.java
new file mode 100644
index 0000000..9003925
--- /dev/null
+++ b/authz-gw/src/main/java/org/onap/aaf/authz/gw/service/GwServiceImpl.java
@@ -0,0 +1,40 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw.service;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.gw.mapper.Mapper;

+

+public class GwServiceImpl<IN,OUT,ERROR> 

+	  implements GwService<IN,OUT,ERROR> {

+	

+		private Mapper<IN,OUT,ERROR> mapper;

+	

+		public GwServiceImpl(AuthzTrans trans, Mapper<IN,OUT,ERROR> mapper) {

+			this.mapper = mapper;

+		}

+		

+		public Mapper<IN,OUT,ERROR> mapper() {return mapper;}

+

+//////////////// APIs ///////////////////

+};

diff --git a/authz-gw/src/main/xsd/gw_1_0.xsd b/authz-gw/src/main/xsd/gw_1_0.xsd
new file mode 100644
index 0000000..d5716dd
--- /dev/null
+++ b/authz-gw/src/main/xsd/gw_1_0.xsd
@@ -0,0 +1,103 @@
+<!-- Used by gw (ATT 2015) -->
+<xs:schema 
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" 
+	xmlns:gw="urn:gw:v1_0" 
+	targetNamespace="urn:gw:v1_0" 
+	elementFormDefault="qualified">
+	
+
+<!-- 
+	Requests
+ -->
+	<xs:complexType name="Request">
+		<xs:sequence>
+		</xs:sequence>
+	</xs:complexType>
+
+<!-- 
+	In 
+-->	
+	<xs:element name="inRequest">
+		<xs:complexType>
+			<xs:complexContent>
+				<xs:extension base="gw:Request">
+					<xs:sequence>
+						<xs:element name="name" type="xs:string"/>
+						<xs:element name="action" type="xs:string"/>
+					</xs:sequence>
+				</xs:extension>
+			</xs:complexContent>
+		</xs:complexType>
+	</xs:element>
+
+
+<!-- 
+	Out 
+-->	
+	<xs:element name="out">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="name" type="xs:string"/>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+
+<!--  **************** STANDARD ELEMENTS ******************* -->
+<!--
+	Errors
+	Note: This Error Structure has been made to conform to the AT&T TSS Policies
+ -->
+	<xs:element name="error">
+		<xs:complexType>
+			<xs:sequence>
+				<!--
+				Unique message identifier of the format ‘ABCnnnn’ where ‘ABC’ is
+					either ‘SVC’ for Service Exceptions or ‘POL’ for Policy Exception.
+					Exception numbers may be in the	range of 0001 to 9999 where :
+					* 0001 to 0199 are reserved for	common exception messages
+					* 0200 to 0999 are reserved for Parlay Web Services specification use
+					* 1000-9999 are available for exceptions 
+				 -->
+				<xs:element name="messageId" type="xs:string" minOccurs="1" maxOccurs="1"/>
+				
+				<!-- 
+				Message text, with replacement
+					variables marked with %n, where n is
+					an index into the list of <variables>
+					elements, starting at 1
+				 -->
+				<xs:element name="text" type="xs:string" minOccurs="1" maxOccurs="1"/>
+				
+				<!-- 
+				List of zero or more strings that
+					represent the contents of the variables
+					used by the message text. -->
+				<xs:element name="variables" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+	
+<!-- 
+	API 
+-->	
+	<xs:element name="api">
+		<xs:complexType>
+			<xs:sequence>
+				<xs:element name="route" minOccurs="0" maxOccurs="unbounded">
+					<xs:complexType>
+						<xs:sequence>
+							<xs:element name="meth" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="path" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="param" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="desc" type="xs:string" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="comments" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="contentType" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+							<xs:element name="expected" type="xs:int" minOccurs="1" maxOccurs="1"/>
+							<xs:element name="explicitErr" type="xs:int" minOccurs="0" maxOccurs="unbounded"/>
+						</xs:sequence>	
+					</xs:complexType>
+				</xs:element>
+			</xs:sequence>
+		</xs:complexType>
+	</xs:element>
+</xs:schema>
\ No newline at end of file
diff --git a/authz-gw/src/test/java/org/onap/aaf/authz/gw/JU_GwAPI.java b/authz-gw/src/test/java/org/onap/aaf/authz/gw/JU_GwAPI.java
new file mode 100644
index 0000000..a820008
--- /dev/null
+++ b/authz-gw/src/test/java/org/onap/aaf/authz/gw/JU_GwAPI.java
@@ -0,0 +1,51 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.gw;

+

+import static org.junit.Assert.*;

+

+import org.junit.Test;

+

+public class JU_GwAPI {

+

+	@Test

+	public void test() {

+		fail("Not yet implemented");

+	}

+	

+	@Test

+	public void testRoute() {

+		fail("Not yet implemented");

+	}

+	

+	@Test

+	public void testRouteAll() {

+		fail("Not yet implemented");

+	}

+	

+	@Test

+	public void testStartDME2() {

+		fail("Not yet implemented");

+	}

+

+}

diff --git a/authz-service/pom.xml b/authz-service/pom.xml
new file mode 100644
index 0000000..677d84d
--- /dev/null
+++ b/authz-service/pom.xml
@@ -0,0 +1,264 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-service</artifactId>

+	<name>Authz Service</name>

+	<description>API for Authorization and Authentication</description>

+		<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>true</maven.test.failure.ignore>

+		<project.swmVersion>1</project.swmVersion>

+			<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+	</properties>

+	

+		

+	<dependencies>

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-client</artifactId>

+        </dependency>

+

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-core</artifactId>

+            <exclusions>

+			  <exclusion> 

+					<groupId>javax.servlet</groupId>

+       			<artifactId>servlet-api</artifactId>

+       		   </exclusion>

+		    </exclusions> 

+        </dependency>

+        

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-cass</artifactId>

+        </dependency>

+

+        <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-defOrg</artifactId>

+            <version>${project.version}</version>

+        </dependency>

+

+

+	

+        <dependency > 

+			<groupId>org.onap.aaf.inno</groupId>

+			<artifactId>env</artifactId>

+		</dependency>

+

+

+		<dependency>

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-core</artifactId>

+		</dependency>

+

+		<dependency>

+			<groupId>com.att.aft</groupId>

+			<artifactId>dme2</artifactId>

+		</dependency>

+

+ 		<dependency>

+			<groupId>org.onap.aaf.inno</groupId>

+			<artifactId>rosetta</artifactId>

+		</dependency>

+		<dependency>

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+		</dependency>

+

+	

+

+       

+	</dependencies>

+	

+	<build>

+	    <plugins>

+	            <plugin>

+	                <groupId>org.codehaus.mojo</groupId>

+	                <artifactId>exec-maven-plugin</artifactId>

+	                <version>1.5.0</version>

+	                <configuration>

+	                    <executable>java</executable>

+	                    <arguments>

+	                        <argument>-DAFT_LATITUDE=33</argument>

+	                        <argument>-DAFT_LONGITUDE=-84</argument>

+	                        <argument>-DAFT_ENVIRONMENT=AFTUAT</argument>

+	

+	                        <argument>-XX:NewRatio=3</argument>

+	                        <argument>-XX:+PrintGCTimeStamps</argument>

+	                        <argument>-XX:+PrintGCDetails</argument>

+	                        <argument>-Xloggc:gc.log</argument>

+	                        <argument>-classpath</argument>

+	

+	                        <classpath>

+	                        

+	                        </classpath>

+	                        <argument>org.onap.aaf.authz.service.AuthAPI</argument>

+	

+	                   <argument>service=org.onap.aaf.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=Dev</argument>

+	                    </arguments>

+	                </configuration>

+	            </plugin>

+	

+	            <plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-jar-plugin</artifactId>

+					<configuration>

+						<excludes>

+	                    	<exclude>*.properties</exclude>

+	                	</excludes>

+					</configuration>

+					<version>2.3.1</version>

+				</plugin>

+

+				<plugin>

+					<groupId>org.apache.maven.plugins</groupId>

+					<artifactId>maven-deploy-plugin</artifactId>

+					<configuration>

+						<skip>true</skip>

+					</configuration>

+			    </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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin> 

+		

+			</plugins>

+

+	</build>

+

+		<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+</project>

diff --git a/authz-service/src/main/assemble/swm.xml b/authz-service/src/main/assemble/swm.xml
new file mode 100644
index 0000000..561d7b4
--- /dev/null
+++ b/authz-service/src/main/assemble/swm.xml
@@ -0,0 +1,35 @@
+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<assembly>

+	<id>swm</id>

+	<formats>

+		<format>zip</format>

+	</formats>

+	

+	<baseDirectory>${artifactId}</baseDirectory>

+	<fileSets>

+		<fileSet>

+			<directory>target/swm</directory>

+		</fileSet>

+	</fileSets>

+</assembly>

diff --git a/authz-service/src/main/config/authAPI.props b/authz-service/src/main/config/authAPI.props
new file mode 100644
index 0000000..6bc7869
--- /dev/null
+++ b/authz-service/src/main/config/authAPI.props
@@ -0,0 +1,24 @@
+##
+## AUTHZ API (authz-service) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+##DME2 related parameters
+
+DMEServiceName=service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_SERVICE_PORT_RANGE_
+
+
+CACHE_HIGH_COUNT=20000
+CACHE_CLEAN_INTERVAL=60000
\ No newline at end of file
diff --git a/authz-service/src/main/config/log4j.properties b/authz-service/src/main/config/log4j.properties
new file mode 100644
index 0000000..75507e7
--- /dev/null
+++ b/authz-service/src/main/config/log4j.properties
@@ -0,0 +1,90 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+###############################################################################

+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.INIT.File=_LOG_DIR_/${LOG4J_FILENAME_init}

+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.INIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.INIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.INIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+

+log4j.appender.SRVR=org.apache.log4j.DailyRollingFileAppender 

+log4j.appender.SRVR.File=logs/${LOG4J_FILENAME_authz}

+log4j.appender.SRVR.DatePattern='.'yyyy-MM-dd

+#log4j.appender.SRVR.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.SRVR.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.SRVR.layout=org.apache.log4j.PatternLayout 

+log4j.appender.SRVR.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %p [%c] %m %n

+

+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.AUDIT.File=_LOG_DIR_/${LOG4J_FILENAME_audit}

+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.AUDIT.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.AUDIT.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.AUDIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.TRACE=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.TRACE.File=logs/${LOG4J_FILENAME_trace}

+log4j.appender.TRACE.DatePattern='.'yyyy-MM-dd

+#log4j.appender.TRACE.MaxFileSize=_MAX_LOG_FILE_SIZE_

+#log4j.appender.TRACE.MaxBackupIndex=_MAX_LOG_FILE_BACKUP_COUNT_

+log4j.appender.TRACE.layout=org.apache.log4j.PatternLayout 

+log4j.appender.TRACE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.stdout=org.apache.log4j.ConsoleAppender

+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN

+log4j.logger.org.apache=WARN,INIT

+log4j.logger.dme2=WARN,INIT

+log4j.logger.init=INFO,INIT

+log4j.logger.authz=_LOG4J_LEVEL_,SRVR

+log4j.logger.audit=INFO,AUDIT

+log4j.logger.trace=TRACE,TRACE

+

+

diff --git a/authz-service/src/main/config/lrm-authz-service.xml b/authz-service/src/main/config/lrm-authz-service.xml
new file mode 100644
index 0000000..ef14fbd
--- /dev/null
+++ b/authz-service/src/main/config/lrm-authz-service.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">

+    <ns2:ManagedResource>

+        <ResourceDescriptor>

+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>

+            <ResourceVersion>

+                <Major>_MAJOR_VER_</Major>

+                <Minor>_MINOR_VER_</Minor>

+                <Patch>_PATCH_VER_</Patch>                

+            </ResourceVersion>

+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>

+        </ResourceDescriptor>

+        <ResourceType>Java</ResourceType>

+        <ResourcePath>com.att.authz.service.AuthzAPI</ResourcePath>

+        <ResourceProps>

+            <Tag>process.workdir</Tag>

+            <Value>_ROOT_DIR_</Value>

+        </ResourceProps>    	       

+        <ResourceProps>

+            <Tag>jvm.version</Tag>

+            <Value>1.8</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.args</Tag>

+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.classpath</Tag>

+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.min</Tag>

+            <Value>1024m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.max</Tag>

+            <Value>2048m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>start.class</Tag>

+            <Value>com.att.authz.service.AuthAPI</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stdout.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stderr.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>

+        </ResourceProps>

+        <ResourceOSID>aft</ResourceOSID>

+        <ResourceStartType>AUTO</ResourceStartType>

+        <ResourceStartPriority>2</ResourceStartPriority>

+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>

+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        

+		<ResourceRegistration>_RESOURCE_REGISTRATION_</ResourceRegistration>

+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>

+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>

+    </ns2:ManagedResource>

+</ns2:ManagedResourceList>

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFLur.java b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFLur.java
new file mode 100644
index 0000000..67dc754
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFLur.java
@@ -0,0 +1,170 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import java.security.Principal;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.PermDAO.Data;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.cadi.Lur;

+import org.onap.aaf.cadi.Permission;

+

+public class DirectAAFLur implements Lur {

+	private final AuthzEnv env;

+	private final Question question;

+	

+	public DirectAAFLur(AuthzEnv env, Question question) {

+		this.env = env;

+		this.question = question;

+	}

+

+	@Override

+	public boolean fish(Principal bait, Permission pond) {

+		return fish(env.newTransNoAvg(),bait,pond);

+	}

+	

+	public boolean fish(AuthzTrans trans, Principal bait, Permission pond) {

+		Result<List<Data>> pdr = question.getPermsByUser(trans, bait.getName(),false);

+		switch(pdr.status) {

+			case OK:

+				for(PermDAO.Data d : pdr.value) {

+					if(new PermPermission(d).match(pond)) return true;

+				}

+				break;

+			default:

+				trans.error().log("Can't access Cassandra to fulfill Permission Query: ",pdr.status,"-",pdr.details);

+		}

+		return false;

+	}

+

+	@Override

+	public void fishAll(Principal bait, List<Permission> permissions) {

+		Result<List<Data>> pdr = question.getPermsByUser(env.newTrans(), bait.getName(),false);

+		switch(pdr.status) {

+			case OK:

+				for(PermDAO.Data d : pdr.value) {

+					permissions.add(new PermPermission(d));

+				}

+				break;

+			default:

+				env.error().log("Can't access Cassandra to fulfill Permission Query: ",pdr.status,"-", pdr.details);

+		}

+	}

+	

+	@Override

+	public void destroy() {

+	}

+

+	@Override

+	public boolean handlesExclusively(Permission pond) {

+		return false;

+	}

+	

+	/**

+	 * Small Class implementing CADI's Permission with Cassandra Data

+	 *

+	 */

+	public static class PermPermission implements Permission {

+		private PermDAO.Data data;

+		

+		public PermPermission(PermDAO.Data d) {

+			data = d;

+		}

+		

+		public PermPermission(AuthzTrans trans, Question q, String p) {

+			data = PermDAO.Data.create(trans, q, p);

+		}

+		

+		public PermPermission(String ns, String type, String instance, String action) {

+			data = new PermDAO.Data();

+			data.ns = ns;

+			data.type = type;

+			data.instance = instance;

+			data.action = action;

+		}

+

+		@Override

+		public String getKey() {

+			return data.type;

+		}

+

+		@Override

+		public boolean match(Permission p) {

+			if(p==null)return false;

+			PermDAO.Data pd;

+			if(p instanceof DirectAAFLur.PermPermission) {

+				pd = ((DirectAAFLur.PermPermission)p).data;

+				if(data.ns.equals(pd.ns))

+					if(data.type.equals(pd.type))

+						if(data.instance!=null && (data.instance.equals(pd.instance) || "*".equals(data.instance)))

+							if(data.action!=null && (data.action.equals(pd.action) || "*".equals(data.action)))

+								return true;

+			} else{

+				String[] lp = p.getKey().split("\\|");

+				if(lp.length<3)return false;

+				if(data.fullType().equals(lp[0]))

+					if(data.instance!=null && (data.instance.equals(lp[1]) || "*".equals(data.instance)))

+						if(data.action!=null && (data.action.equals(lp[2]) || "*".equals(data.action)))

+							return true;

+			}

+			return false;

+		}

+

+		@Override

+		public String permType() {

+			return "AAFLUR";

+		}

+		

+	}

+	

+	public String toString() {

+		return "DirectAAFLur is enabled";

+		

+	}

+

+	@Override

+	public boolean supports(String userName) {

+		//TODO

+		return true;

+	}

+

+	@Override

+	public Permission createPerm(String p) {

+		// TODO Auto-generated method stub

+		return null;

+	}

+

+	@Override

+	public void clear(Principal p, StringBuilder report) {

+		// TODO Auto-generated method stub

+		

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFUserPass.java b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFUserPass.java
new file mode 100644
index 0000000..263c94e
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectAAFUserPass.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+

+import java.util.Date;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.cadi.CredVal;

+

+/**

+ * DirectAAFUserPass is intended to provide password Validation directly from Cassandra Database, and is only

+ * intended for use in AAF itself.  The normal "AAF Taf" objects are, of course, clients.

+ * 

+ *

+ */

+public class DirectAAFUserPass implements CredVal {

+		private final AuthzEnv env;

+	private final Question question;

+	

+	public DirectAAFUserPass(AuthzEnv env, Question question, String appPass) {

+		this.env = env;

+		this.question = question;

+	}

+	

+	@Override

+	public boolean validate(String user, Type type, byte[] pass) {

+		try {

+			AuthzTrans trans = env.newTransNoAvg();

+			Result<Date> result = question.doesUserCredMatch(trans, user, pass);

+			trans.logAuditTrail(env.info());

+			switch(result.status) {

+				case OK:

+					return true;

+				default:

+					

+					env.warn().log(user, "failed Password Validation:",result.errorString());

+			}

+		} catch (DAOException e) {

+			System.out.println(" exception in DirectAAFUserPass class ");

+			e.printStackTrace();

+			env.error().log(e,"Cannot validate User/Pass from Cassandra");

+		}

+		return false;

+	}

+

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectCertIdentity.java b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectCertIdentity.java
new file mode 100644
index 0000000..7df3adc
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/cadi/DirectCertIdentity.java
@@ -0,0 +1,79 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import java.nio.ByteBuffer;

+import java.security.Principal;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+import java.util.List;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.TransFilter;

+import org.onap.aaf.dao.aaf.cached.CachedCertDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO.Data;

+

+import org.onap.aaf.cadi.principal.X509Principal;

+import org.onap.aaf.cadi.taf.cert.CertIdentity;

+import org.onap.aaf.cadi.taf.cert.X509Taf;

+

+/**

+ * Direct view of CertIdentities

+ * 

+ * Warning:  this class is difficult to instantiate.  The only service that can use it is AAF itself, and is thus 

+ * entered in the "init" after the CachedCertDAO is created.

+ * 

+ *

+ */

+public class DirectCertIdentity implements CertIdentity {

+	private static CachedCertDAO certDAO;

+

+	@Override

+	public Principal identity(HttpServletRequest req, X509Certificate cert,	byte[] _certBytes) throws CertificateException {

+	    	byte[] certBytes = _certBytes;

+		if(cert==null && certBytes==null) {

+		    return null;

+		}

+		if(certBytes==null) {

+		    certBytes = cert.getEncoded();

+		}

+		byte[] fingerprint = X509Taf.getFingerPrint(certBytes);

+

+		AuthzTrans trans = (AuthzTrans) req.getAttribute(TransFilter.TRANS_TAG);

+		

+		Result<List<Data>> cresp = certDAO.read(trans, ByteBuffer.wrap(fingerprint));

+		if(cresp.isOKhasData()) {

+			Data cdata = cresp.value.get(0);

+			return new X509Principal(cdata.id,cert,certBytes);

+		}

+		return null;

+	}

+

+	public static void set(CachedCertDAO ccd) {

+		certDAO = ccd;

+	}

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade.java b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade.java
new file mode 100644
index 0000000..69df9c6
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade.java
@@ -0,0 +1,263 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.facade;

+

+import java.util.Date;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.cssa.rserv.RServlet;

+import org.onap.aaf.dao.aaf.cass.NsType;

+

+/**

+ * AuthzFacade

+ *   This layer is responsible for covering the Incoming Messages, be they XML, JSON or just entries on the URL,

+ *   and converting them to data that can be called on the Service Layer.

+ *   

+ *   Upon response, this layer, because it knew the incoming Data Formats (i.e. XML/JSON), the HTTP call types

+ *   are set on "ContentType" on Response.

+ *   

+ *   Finally, we wrap the call in Time Stamps with explanation of what is happing for Audit trails.

+ *   

+ *

+ */

+public interface AuthzFacade {

+	public static final int PERM_DEPEND_424 = -1000;

+	public static final int ROLE_DEPEND_424 = -1001;

+

+	/*

+	 * Namespaces

+	 */

+	public abstract Result<Void> requestNS(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, NsType type);

+	

+	public abstract Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns);

+	

+	public abstract Result<Void> getNSsByAdmin(AuthzTrans trans, HttpServletResponse resp, String user, boolean full);

+	

+	public abstract Result<Void> getNSsByResponsible(AuthzTrans trans, HttpServletResponse resp, String user, boolean full);

+	

+	public abstract Result<Void> getNSsByEither(AuthzTrans trans, HttpServletResponse resp, String user, boolean full);

+

+	public abstract Result<Void> getNSsChildren(AuthzTrans trans, HttpServletResponse resp, String pathParam);

+

+	public abstract Result<Void> addAdminToNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id);

+

+	public abstract Result<Void> delAdminFromNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id);

+

+	public abstract Result<Void> addResponsibilityForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id);

+

+	public abstract Result<Void> delResponsibilityForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id);

+	

+	public abstract Result<Void> updateNsDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	public abstract Result<Void> deleteNS(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, String ns);

+

+	// NS Attribs

+	public abstract Result<Void> createAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key, String value);

+

+	public abstract Result<Void> readNsByAttrib(AuthzTrans trans, HttpServletResponse resp, String key);

+

+	public abstract Result<Void> updAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key, String value);

+

+	public abstract Result<Void> delAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key);

+

+	/*

+	 * Permissions

+	 */

+	public abstract Result<Void> createPerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);	

+	

+	public abstract Result<Void> getPermsByName(AuthzTrans trans, HttpServletResponse resp, 

+			String type, String instance, String action);

+

+	public abstract Result<Void> getPermsByUser(AuthzTrans trans, HttpServletResponse response, String user);

+	

+	public abstract Result<Void> getPermsByUserWithAAFQuery(AuthzTrans trans, HttpServletRequest request, HttpServletResponse response, String user);

+

+	public abstract Result<Void> getPermsByType(AuthzTrans trans, HttpServletResponse resp, String type);

+

+	public abstract Result<Void> getPermsForRole(AuthzTrans trans, HttpServletResponse response, String roleName);

+

+	public abstract Result<Void> getPermsByNS(AuthzTrans trans, HttpServletResponse response, String ns);

+	

+	public abstract Result<Void> renamePerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp,

+			String type, String instance, String action);

+	

+	public abstract Result<Void> updatePermDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> resetPermRoles(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	public abstract Result<Void> deletePerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	public abstract Result<Void> deletePerm(AuthzTrans trans,	HttpServletResponse resp, 

+			String perm, String type, String action);

+

+	/*

+	 * Roles

+	 */

+	public abstract Result<Void> createRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse response);

+	

+	public abstract Result<Void> getRolesByName(AuthzTrans trans,HttpServletResponse resp, String name);

+

+	public abstract Result<Void> getRolesByNS(AuthzTrans trans, HttpServletResponse resp, String ns);

+

+	public abstract Result<Void> getRolesByNameOnly(AuthzTrans trans, HttpServletResponse resp, String nameOnly);

+

+	public abstract Result<Void> getRolesByUser(AuthzTrans trans, HttpServletResponse resp, String user);

+

+	public abstract Result<Void> getRolesByPerm(AuthzTrans trans, HttpServletResponse resp, String type, String instance, String action);

+

+	public abstract Result<Void> updateRoleDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> addPermToRole(AuthzTrans trans,HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> delPermFromRole(AuthzTrans trans,HttpServletRequest req, HttpServletResponse resp);

+

+	public abstract Result<Void> deleteRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	public abstract Result<Void> deleteRole(AuthzTrans trans, HttpServletResponse resp, String role);

+

+	/*

+	 * Users

+	 */

+	

+	public abstract Result<Void> getUsersByRole(AuthzTrans trans, HttpServletResponse resp, String role);

+	

+	public abstract Result<Void> getUsersByPermission(AuthzTrans trans, HttpServletResponse resp, 

+			String type, String instance, String action);

+

+

+

+	/*

+	 * Delegates

+	 */

+	public abstract Result<Void> createDelegate(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> updateDelegate(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> deleteDelegate(AuthzTrans trans,  HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> deleteDelegate(AuthzTrans trans,  String user);

+	

+	public abstract Result<Void> getDelegatesByUser(AuthzTrans trans, String userName, HttpServletResponse resp);

+

+	public abstract Result<Void> getDelegatesByDelegate(AuthzTrans trans, String userName, HttpServletResponse resp);

+

+	/*

+	 * Credentials

+	 */

+	public abstract Result<Void> createUserCred(AuthzTrans trans, HttpServletRequest req);

+

+	public abstract Result<Void> changeUserCred(AuthzTrans trans, HttpServletRequest req);

+

+	public abstract Result<Void> extendUserCred(AuthzTrans trans, HttpServletRequest req, String days);

+

+	public abstract Result<Void> getCredsByNS(AuthzTrans trans,	HttpServletResponse resp, String ns);

+

+	public abstract Result<Void> getCredsByID(AuthzTrans trans, HttpServletResponse resp, String id);

+

+	public abstract Result<Void> deleteUserCred(AuthzTrans trans, HttpServletRequest req);

+

+	public abstract Result<Void> validBasicAuth(AuthzTrans trans, HttpServletResponse resp, String basicAuth);

+

+	public abstract Result<Date> doesCredentialMatch(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+

+	/*

+	 * Miscellaneous

+	 */

+	/**

+	 * Place Standard Messages based on HTTP Code onto Error Data Structure, and write to OutputStream

+	 * Log message

+	 */

+	public abstract void error(AuthzTrans trans, HttpServletResponse response, Result<?> result);

+

+	/*

+	 * UserRole

+	 */

+	public abstract Result<Void> requestUserRole(AuthzTrans trans,HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> getUserInRole(AuthzTrans trans, HttpServletResponse resp, String user, String role);

+	

+	public abstract Result<Void> getUserRolesByRole(AuthzTrans trans, HttpServletResponse resp, String role);

+	

+	public abstract Result<Void> getUserRolesByUser(AuthzTrans trans, HttpServletResponse resp, String user);

+

+	public abstract Result<Void> deleteUserRole(AuthzTrans trans, HttpServletResponse resp, String user, String role);

+	

+	public abstract Result<Void> resetUsersForRole(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req);

+

+	public abstract Result<Void> resetRolesForUser(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req);

+	

+	public abstract Result<Void> extendUserRoleExpiration(AuthzTrans trans, HttpServletResponse resp, String user,

+	String role);

+

+	/*

+	 * Approval 

+	 */

+	public abstract Result<Void> updateApproval(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp);

+	

+	public abstract Result<Void> getApprovalsByUser(AuthzTrans trans, HttpServletResponse resp, String user);

+	

+	public abstract Result<Void> getApprovalsByTicket(AuthzTrans trans, HttpServletResponse resp, String ticket);

+	

+	public abstract Result<Void> getApprovalsByApprover(AuthzTrans trans, HttpServletResponse resp, String approver);

+

+

+	/*

+	 * History

+	 */

+	public abstract Result<Void> getHistoryByUser(AuthzTrans trans,	HttpServletResponse resp, String user, int[] yyyymm, final int sort);

+	

+	public abstract Result<Void> getHistoryByRole(AuthzTrans trans,	HttpServletResponse resp, String subject, int[] yyyymm, final int sort);

+

+	public abstract Result<Void> getHistoryByPerm(AuthzTrans trans,	HttpServletResponse resp, String subject, int[] yyyymm, final int sort);

+

+	public abstract Result<Void> getHistoryByNS(AuthzTrans trans,	HttpServletResponse resp, String subject, int[] yyyymm, final int sort);

+

+	/*

+	 * Cache 

+	 */

+	public abstract Result<Void> cacheClear(AuthzTrans trans, String pathParam);

+

+	public abstract Result<Void> cacheClear(AuthzTrans trans, String string,String segments);

+	

+	public abstract void dbReset(AuthzTrans trans);

+

+

+

+	/*

+	 * API

+	 */

+	public Result<Void> getAPI(AuthzTrans trans, HttpServletResponse resp, RServlet<AuthzTrans> rservlet);

+

+	public abstract Result<Void> getAPIExample(AuthzTrans trans, HttpServletResponse resp, String typeCode, boolean optional);

+

+	public abstract Result<Void> getCertInfoByID(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, String id);

+

+

+

+

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeFactory.java b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeFactory.java
new file mode 100644
index 0000000..8097317
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeFactory.java
@@ -0,0 +1,57 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.facade;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.service.AuthzCassServiceImpl;

+import org.onap.aaf.authz.service.mapper.Mapper_2_0;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+

+public class AuthzFacadeFactory {

+	public static AuthzFacade_2_0 v2_0(AuthzEnv env, AuthzTrans trans, Data.TYPE type, Question question) throws APIException {

+		return new AuthzFacade_2_0(env,

+				new AuthzCassServiceImpl<

+					aaf.v2_0.Nss,

+					aaf.v2_0.Perms,

+					aaf.v2_0.Pkey,

+					aaf.v2_0.Roles,

+					aaf.v2_0.Users,

+					aaf.v2_0.UserRoles,

+					aaf.v2_0.Delgs,

+					aaf.v2_0.Certs,

+					aaf.v2_0.Keys,

+					aaf.v2_0.Request,

+					aaf.v2_0.History,

+					aaf.v2_0.Error,

+					aaf.v2_0.Approvals>

+					(trans,new Mapper_2_0(question),question),

+				type);

+	}

+	

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeImpl.java b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeImpl.java
new file mode 100644
index 0000000..d35a95a
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacadeImpl.java
@@ -0,0 +1,2565 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.facade;

+

+import static org.onap.aaf.authz.layer.Result.ERR_ActionNotCompleted;

+import static org.onap.aaf.authz.layer.Result.ERR_Backend;

+import static org.onap.aaf.authz.layer.Result.ERR_BadData;

+import static org.onap.aaf.authz.layer.Result.ERR_ConflictAlreadyExists;

+import static org.onap.aaf.authz.layer.Result.ERR_Denied;

+import static org.onap.aaf.authz.layer.Result.ERR_NotFound;

+import static org.onap.aaf.authz.layer.Result.ERR_NotImplemented;

+import static org.onap.aaf.authz.layer.Result.ERR_Policy;

+import static org.onap.aaf.authz.layer.Result.ERR_Security;

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_ChoiceNeeded;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_DelegateNotFound;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_DependencyExists;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_FutureNotRequested;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_InvalidDelegate;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_NsNotFound;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_PermissionNotFound;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_RoleNotFound;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_UserNotFound;

+import static org.onap.aaf.dao.aaf.cass.Status.ERR_UserRoleNotFound;

+

+import java.io.IOException;

+import java.lang.reflect.Method;

+import java.util.Date;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.FacadeImpl;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthzCassServiceImpl;

+import org.onap.aaf.authz.service.AuthzService;

+import org.onap.aaf.authz.service.mapper.Mapper;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.cssa.rserv.RServlet;

+import org.onap.aaf.cssa.rserv.RouteReport;

+import org.onap.aaf.cssa.rserv.doc.ApiDoc;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import org.onap.aaf.cadi.aaf.client.Examples;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Data.TYPE;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.util.Chrono;

+import org.onap.aaf.rosetta.Marshal;

+import org.onap.aaf.rosetta.env.RosettaDF;

+import org.onap.aaf.rosetta.env.RosettaData;

+

+import aaf.v2_0.Api;

+

+/**

+ * AuthzFacade

+ * 

+ * This Service Facade encapsulates the essence of the API Service can do, and provides

+ * a single created object for elements such as RosettaDF.

+ *

+ * The Responsibilities of this class are to:

+ * 1) Interact with the Service Implementation (which might be supported by various kinds of Backend Storage)

+ * 2) Validate incoming data (if applicable)

+ * 3) Convert the Service response into the right Format, and mark the Content Type

+ * 		a) In the future, we may support multiple Response Formats, aka JSON or XML, based on User Request.

+ * 4) Log Service info, warnings and exceptions as necessary

+ * 5) When asked by the API layer, this will create and write Error content to the OutputStream

+ * 

+ * Note: This Class does NOT set the HTTP Status Code.  That is up to the API layer, so that it can be 

+ * clearly coordinated with the API Documentation

+ * 

+ *

+ */

+public abstract class AuthzFacadeImpl<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> extends FacadeImpl implements AuthzFacade 

+	{

+	private static final String FORBIDDEN = "Forbidden";

+	private static final String NOT_FOUND = "Not Found";

+	private static final String NOT_ACCEPTABLE = "Not Acceptable";

+	private static final String GENERAL_SERVICE_ERROR = "General Service Error";

+	private static final String NO_DATA = "***No Data***";

+	private AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> service = null;

+	private final RosettaDF<NSS> nssDF;

+	private final RosettaDF<PERMS> permsDF;

+	private final RosettaDF<ROLES> roleDF;

+	private final RosettaDF<USERS> usersDF;

+	private final RosettaDF<USERROLES> userrolesDF;

+	private final RosettaDF<CERTS> certsDF;

+	private final RosettaDF<DELGS> delgDF;

+	private final RosettaDF<REQUEST> permRequestDF;

+	private final RosettaDF<REQUEST> roleRequestDF;

+	private final RosettaDF<REQUEST> userRoleRequestDF;

+	private final RosettaDF<REQUEST> rolePermRequestDF;

+	private final RosettaDF<REQUEST> nsRequestDF;

+	private final RosettaDF<REQUEST> credRequestDF;

+	private final RosettaDF<REQUEST> delgRequestDF;

+	private final RosettaDF<HISTORY> historyDF;

+	private final RosettaDF<KEYS>    keysDF;

+

+	private final RosettaDF<ERR> 	 	errDF;

+	private final RosettaDF<APPROVALS>  approvalDF;

+	// Note: Api is not different per Version

+	private final RosettaDF<Api>	 	apiDF;

+

+

+	@SuppressWarnings("unchecked")

+	public AuthzFacadeImpl(AuthzEnv env, AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> service, Data.TYPE dataType) throws APIException {

+		this.service = service;

+		(nssDF 				= env.newDataFactory(service.mapper().getClass(API.NSS))).in(dataType).out(dataType);

+		(permRequestDF 		= env.newDataFactory(service.mapper().getClass(API.PERM_REQ))).in(dataType).out(dataType);

+		(permsDF 			= env.newDataFactory(service.mapper().getClass(API.PERMS))).in(dataType).out(dataType);

+//		(permKeyDF			= env.newDataFactory(service.mapper().getClass(API.PERM_KEY))).in(dataType).out(dataType);

+		(roleDF 			= env.newDataFactory(service.mapper().getClass(API.ROLES))).in(dataType).out(dataType);

+		(roleRequestDF 		= env.newDataFactory(service.mapper().getClass(API.ROLE_REQ))).in(dataType).out(dataType);

+		(usersDF 			= env.newDataFactory(service.mapper().getClass(API.USERS))).in(dataType).out(dataType);

+		(userrolesDF 			= env.newDataFactory(service.mapper().getClass(API.USER_ROLES))).in(dataType).out(dataType);

+		(certsDF 			= env.newDataFactory(service.mapper().getClass(API.CERTS))).in(dataType).out(dataType)

+			.rootMarshal((Marshal<CERTS>) service.mapper().getMarshal(API.CERTS));

+		;

+		(userRoleRequestDF 	= env.newDataFactory(service.mapper().getClass(API.USER_ROLE_REQ))).in(dataType).out(dataType);

+		(rolePermRequestDF 	= env.newDataFactory(service.mapper().getClass(API.ROLE_PERM_REQ))).in(dataType).out(dataType);

+		(nsRequestDF 		= env.newDataFactory(service.mapper().getClass(API.NS_REQ))).in(dataType).out(dataType);

+		(credRequestDF 		= env.newDataFactory(service.mapper().getClass(API.CRED_REQ))).in(dataType).out(dataType);

+		(delgRequestDF 		= env.newDataFactory(service.mapper().getClass(API.DELG_REQ))).in(dataType).out(dataType);

+		(historyDF 			= env.newDataFactory(service.mapper().getClass(API.HISTORY))).in(dataType).out(dataType);

+		( keysDF 			= env.newDataFactory(service.mapper().getClass(API.KEYS))).in(dataType).out(dataType);

+		(delgDF 			= env.newDataFactory(service.mapper().getClass(API.DELGS))).in(dataType).out(dataType);

+		(approvalDF 		= env.newDataFactory(service.mapper().getClass(API.APPROVALS))).in(dataType).out(dataType);

+		(errDF 				= env.newDataFactory(service.mapper().getClass(API.ERROR))).in(dataType).out(dataType);

+		(apiDF				= env.newDataFactory(Api.class)).in(dataType).out(dataType);

+	}

+	

+	public Mapper<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper() {

+		return service.mapper();

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#error(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, int)

+	 * 

+	 * Note: Conforms to AT&T TSS RESTful Error Structure

+	 */

+	@Override

+	public void error(AuthzTrans trans, HttpServletResponse response, Result<?> result) {

+		String msg = result.details==null?"%s":"%s - " + result.details.trim();

+		String msgId;

+		String[] detail;

+		if(result.variables==null) {

+			detail = new String[1];

+		} else {

+			int l = result.variables.length;

+			detail=new String[l+1];

+			System.arraycopy(result.variables, 0, detail, 1, l);

+		}

+		//int httpstatus;

+		

+		switch(result.status) {

+			case ERR_ActionNotCompleted:

+				msgId = "SVC1202";

+				detail[0] = "Accepted, Action not complete";

+				response.setStatus(/*httpstatus=*/202);

+				break;

+

+			case ERR_Policy:

+				msgId = "SVC3403";

+				detail[0] = FORBIDDEN;

+				response.setStatus(/*httpstatus=*/403);

+				break;

+			case ERR_Security:

+				msgId = "SVC2403";

+				detail[0] = FORBIDDEN;

+				response.setStatus(/*httpstatus=*/403);

+				break;

+			case ERR_Denied:

+				msgId = "SVC1403";

+				detail[0] = FORBIDDEN;

+				response.setStatus(/*httpstatus=*/403);

+				break;

+			// This is still forbidden to directly impact, but can be Requested when passed

+			// with "request=true" query Param

+			case ERR_FutureNotRequested:

+				msgId = "SVC2403";

+				detail[0] = msg;

+				response.setStatus(/*httpstatus=*/403);

+				break;

+				

+			case ERR_NsNotFound:

+				msgId = "SVC2404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_RoleNotFound:

+				msgId = "SVC3404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_PermissionNotFound:

+				msgId = "SVC4404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_UserNotFound:

+				msgId = "SVC5404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_UserRoleNotFound:

+				msgId = "SVC6404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_DelegateNotFound:

+				msgId = "SVC7404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+			case ERR_NotFound:

+				msgId = "SVC1404";

+				detail[0] = NOT_FOUND;

+				response.setStatus(/*httpstatus=*/404);

+				break;

+

+			case ERR_InvalidDelegate:

+				msgId="SVC2406";

+				detail[0] = NOT_ACCEPTABLE;

+				response.setStatus(/*httpstatus=*/406);

+				break;

+			case ERR_BadData:

+				msgId="SVC1406";

+				detail[0] = NOT_ACCEPTABLE;

+				response.setStatus(/*httpstatus=*/406);

+				break;

+				

+			case ERR_ConflictAlreadyExists:

+				msgId = "SVC1409";

+				detail[0] = "Conflict Already Exists";

+				response.setStatus(/*httpstatus=*/409);

+				break;

+			

+			case ERR_DependencyExists:

+				msgId = "SVC1424";

+				detail[0] = "Failed Dependency";

+				response.setStatus(/*httpstatus=*/424);

+				break;

+			

+			case ERR_NotImplemented:

+				msgId = "SVC1501";

+				detail[0] = "Not Implemented"; 

+				response.setStatus(/*httpstatus=*/501);

+				break;

+				

+			case Status.ACC_Future:

+				msgId = "SVC1202";

+				detail[0] = "Accepted for Future, pending Approvals";

+				response.setStatus(/*httpstatus=*/202);

+				break;

+			case ERR_ChoiceNeeded:

+				msgId = "SVC1300";

+				detail = result.variables;

+				response.setStatus(/*httpstatus=*/300);

+				break;

+			case ERR_Backend: 

+				msgId = "SVC2500";

+				detail[0] = GENERAL_SERVICE_ERROR;

+				response.setStatus(/*httpstatus=*/500);

+				break;

+

+			default: 

+				msgId = "SVC1500";

+				detail[0] = GENERAL_SERVICE_ERROR;

+				response.setStatus(/*httpstatus=*/500);

+				break;

+		}

+

+		try {

+			StringBuilder holder = new StringBuilder();

+			errDF.newData(trans).load(

+				service.mapper()

+					.errorFromMessage(holder,msgId,msg,detail))

+						.to(response.getOutputStream());

+			trans.checkpoint(

+					holder.toString(),

+//					String.format("ErrResp [" +	msgId +	"] " + msg,(Object[])detail),

+					Env.ALWAYS);

+		} catch (Exception e) {

+			trans.error().log(e,"unable to send response for",msg);

+		}

+	}

+	

+	///////////////////////////

+	// Namespace

+	///////////////////////////

+	public static final String CREATE_NS = "createNamespace";

+	public static final String ADD_NS_ADMIN = "addNamespaceAdmin";

+	public static final String DELETE_NS_ADMIN = "delNamespaceAdmin";

+	public static final String ADD_NS_RESPONSIBLE = "addNamespaceResponsible";

+	public static final String DELETE_NS_RESPONSIBLE = "delNamespaceResponsible";

+	public static final String GET_NS_BY_NAME = "getNamespaceByName";

+	public static final String GET_NS_BY_ADMIN = "getNamespaceByAdmin";

+	public static final String GET_NS_BY_RESPONSIBLE = "getNamespaceByResponsible";

+	public static final String GET_NS_BY_EITHER = "getNamespaceByEither";

+	public static final String GET_NS_CHILDREN = "getNamespaceChildren";

+	public static final String UPDATE_NS_DESC = "updateNamespaceDescription";

+	public static final String DELETE_NS = "deleteNamespace";

+	

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#createNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

+	 */

+	@Override

+	public Result<Void> requestNS(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, NsType type) {

+		TimeTaken tt = trans.start(CREATE_NS, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST request;

+			try {

+				Data<REQUEST> rd = nsRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,rd.asString());

+				}

+				request = rd.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_NS);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.createNS(trans,request,type);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,CREATE_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#addAdminToNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> addAdminToNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id) {

+		TimeTaken tt = trans.start(ADD_NS_ADMIN + ' ' + ns + ' ' + id, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.addAdminNS(trans,ns,id);

+			switch(rp.status) {

+				case OK: 

+					//TODO Perms??

+					setContentType(resp,nsRequestDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,ADD_NS_ADMIN);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#delAdminFromNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> delAdminFromNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id) {

+		TimeTaken tt = trans.start(DELETE_NS_ADMIN + ' ' + ns + ' ' + id, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.delAdminNS(trans, ns, id);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_NS_ADMIN);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#addAdminToNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> addResponsibilityForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id) {

+		TimeTaken tt = trans.start(ADD_NS_RESPONSIBLE + ' ' + ns + ' ' + id, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.addResponsibleNS(trans,ns,id);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,ADD_NS_RESPONSIBLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#delAdminFromNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> delResponsibilityForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String id) {

+		TimeTaken tt = trans.start(DELETE_NS_RESPONSIBLE + ' ' + ns + ' ' + id, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.delResponsibleNS(trans, ns, id);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_NS_RESPONSIBLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getNSsByName(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getNSsByName(AuthzTrans trans, HttpServletResponse resp, String ns) {

+		TimeTaken tt = trans.start(GET_NS_BY_NAME + ' ' + ns, Env.SUB|Env.ALWAYS);

+		try {

+			Result<NSS> rp = service.getNSbyName(trans, ns);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<NSS> data = nssDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,nssDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_NS_BY_NAME);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+//	TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getNSsByAdmin(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getNSsByAdmin(AuthzTrans trans, HttpServletResponse resp, String user, boolean full){

+		TimeTaken tt = trans.start(GET_NS_BY_ADMIN + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<NSS> rp = service.getNSbyAdmin(trans, user, full);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<NSS> data = nssDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,nssDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_NS_BY_ADMIN);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+//	TODO: uncomment when on cassandra 2.1.2 for MyNamespace GUI page

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getNSsByResponsible(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getNSsByResponsible(AuthzTrans trans, HttpServletResponse resp, String user, boolean full){

+		TimeTaken tt = trans.start(GET_NS_BY_RESPONSIBLE + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<NSS> rp = service.getNSbyResponsible(trans, user, full);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<NSS> data = nssDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+

+					setContentType(resp,nssDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_NS_BY_RESPONSIBLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getNSsByResponsible(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getNSsByEither(AuthzTrans trans, HttpServletResponse resp, String user, boolean full){

+		TimeTaken tt = trans.start(GET_NS_BY_EITHER + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<NSS> rp = service.getNSbyEither(trans, user, full);

+			

+			switch(rp.status) {

+				case OK: 

+					RosettaData<NSS> data = nssDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+

+					setContentType(resp,nssDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_NS_BY_EITHER);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getNSsByResponsible(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getNSsChildren(AuthzTrans trans, HttpServletResponse resp, String parent){

+		TimeTaken tt = trans.start(GET_NS_CHILDREN + ' ' + parent, Env.SUB|Env.ALWAYS);

+		try {

+			Result<NSS> rp = service.getNSsChildren(trans, parent);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<NSS> data = nssDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,nssDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_NS_CHILDREN);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> updateNsDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_NS_DESC, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = nsRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,UPDATE_NS_DESC);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.updateNsDescription(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_NS_DESC);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#requestNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

+	 */

+	@Override

+	public Result<Void> deleteNS(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, String ns) {

+		TimeTaken tt = trans.start(DELETE_NS + ' ' + ns, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.deleteNS(trans,ns);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,nsRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	private final static String NS_CREATE_ATTRIB = "nsCreateAttrib";

+	private final static String NS_UPDATE_ATTRIB = "nsUpdateAttrib";

+	private final static String READ_NS_BY_ATTRIB = "readNsByAttrib";

+	private final static String NS_DELETE_ATTRIB = "nsDeleteAttrib";

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#createAttribForNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> createAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key, String value) {

+		TimeTaken tt = trans.start(NS_CREATE_ATTRIB + ' ' + ns + ':'+key+':'+value, Env.SUB|Env.ALWAYS);

+		try {

+			Result<?> rp = service.createNsAttrib(trans,ns,key,value);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp, keysDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,NS_CREATE_ATTRIB);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#readAttribForNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> readNsByAttrib(AuthzTrans trans, HttpServletResponse resp, String key) {

+		TimeTaken tt = trans.start(READ_NS_BY_ATTRIB + ' ' + key, Env.SUB|Env.ALWAYS);

+		try {

+			Result<KEYS> rp = service.readNsByAttrib(trans, key);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<KEYS> data = keysDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,keysDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,READ_NS_BY_ATTRIB);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#updAttribForNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> updAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key, String value) {

+		TimeTaken tt = trans.start(NS_UPDATE_ATTRIB + ' ' + ns + ':'+key+':'+value, Env.SUB|Env.ALWAYS);

+		try {

+			Result<?> rp = service.updateNsAttrib(trans,ns,key,value);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp, keysDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,NS_UPDATE_ATTRIB);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#delAttribForNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> delAttribForNS(AuthzTrans trans, HttpServletResponse resp, String ns, String key) {

+		TimeTaken tt = trans.start(NS_DELETE_ATTRIB + ' ' + ns + ':'+key, Env.SUB|Env.ALWAYS);

+		try {

+			Result<?> rp = service.deleteNsAttrib(trans,ns,key);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp, keysDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,NS_DELETE_ATTRIB);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+//

+// PERMISSION

+//

+	public static final String CREATE_PERMISSION = "createPermission";

+	public static final String GET_PERMS_BY_TYPE = "getPermsByType";

+	public static final String GET_PERMS_BY_NAME = "getPermsByName";

+	public static final String GET_PERMISSIONS_BY_USER = "getPermissionsByUser";

+	public static final String GET_PERMISSIONS_BY_USER_WITH_QUERY = "getPermissionsByUserWithQuery";

+	public static final String GET_PERMISSIONS_BY_ROLE = "getPermissionsByRole";

+	public static final String GET_PERMISSIONS_BY_NS = "getPermissionsByNS";

+	public static final String UPDATE_PERMISSION = "updatePermission";

+	public static final String UPDATE_PERM_DESC = "updatePermissionDescription";

+	public static final String SET_PERMISSION_ROLES_TO = "setPermissionRolesTo";

+	public static final String DELETE_PERMISSION = "deletePermission";

+	

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#createOrUpdatePerm(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, boolean, java.lang.String, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> createPerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start( CREATE_PERMISSION, Env.SUB|Env.ALWAYS);	

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = permRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();			

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_PERMISSION);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.createPerm(trans,rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,CREATE_PERMISSION);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getChildPerms(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getPermsByType(AuthzTrans trans, HttpServletResponse resp, String perm) {

+		TimeTaken tt = trans.start(GET_PERMS_BY_TYPE + ' ' + perm, Env.SUB|Env.ALWAYS);

+		try {

+			

+			Result<PERMS> rp = service.getPermsByType(trans, perm);

+			switch(rp.status) {

+				case OK:

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMS_BY_TYPE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> getPermsByName(AuthzTrans trans, HttpServletResponse resp, 

+			String type, String instance, String action) {

+		

+		TimeTaken tt = trans.start(GET_PERMS_BY_NAME + ' ' + type

+				+ '|' + instance + '|' + action, Env.SUB|Env.ALWAYS);

+		try {

+			

+			Result<PERMS> rp = service.getPermsByName(trans, type, instance, action);

+			switch(rp.status) {

+				case OK:

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMS_BY_TYPE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getPermissionByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getPermsByUser(AuthzTrans trans, HttpServletResponse resp,	String user) {

+		TimeTaken tt = trans.start(GET_PERMISSIONS_BY_USER + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<PERMS> rp = service.getPermsByUser(trans, user);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMISSIONS_BY_USER, user);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getPermissionByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getPermsByUserWithAAFQuery(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, String user) {

+		TimeTaken tt = trans.start(GET_PERMISSIONS_BY_USER_WITH_QUERY + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			PERMS perms;

+			try {

+				RosettaData<PERMS> data = permsDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				perms = data.asObject();			

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_PERMISSION);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+

+			Result<PERMS> rp = service.getPermsByUser(trans, perms, user);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMISSIONS_BY_USER_WITH_QUERY , user);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getPermissionsForRole(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getPermsForRole(AuthzTrans trans, HttpServletResponse resp,	String roleName) {

+		TimeTaken tt = trans.start(GET_PERMISSIONS_BY_ROLE + ' ' + roleName, Env.SUB|Env.ALWAYS);

+		try {

+			Result<PERMS> rp = service.getPermsByRole(trans, roleName);

+			switch(rp.status) {

+				case OK:

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMISSIONS_BY_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> getPermsByNS(AuthzTrans trans,HttpServletResponse resp,String ns) {

+		TimeTaken tt = trans.start(GET_PERMISSIONS_BY_NS + ' ' + ns, Env.SUB|Env.ALWAYS);

+		try {

+			Result<PERMS> rp = service.getPermsByNS(trans, ns);

+			switch(rp.status) {

+				case OK:

+					RosettaData<PERMS> data = permsDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_PERMISSIONS_BY_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#createOrUpdatePerm(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, boolean, java.lang.String, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> renamePerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp,

+			String origType, String origInstance, String origAction) {

+		String cmdDescription = UPDATE_PERMISSION;

+		TimeTaken tt = trans.start( cmdDescription	+ ' ' + origType + ' ' + origInstance + ' ' + origAction, Env.SUB|Env.ALWAYS);	

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = permRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();			

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,cmdDescription);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.renamePerm(trans,rreq, origType, origInstance, origAction);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,cmdDescription);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> updatePermDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_PERM_DESC, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = permRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,UPDATE_PERM_DESC);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.updatePermDescription(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_PERM_DESC);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	

+	@Override

+	public Result<Void> resetPermRoles(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(SET_PERMISSION_ROLES_TO, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = rolePermRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN, SET_PERMISSION_ROLES_TO);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.resetPermRoles(trans, rreq);

+			

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,SET_PERMISSION_ROLES_TO);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> deletePerm(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DELETE_PERMISSION, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = permRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,DELETE_PERMISSION);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+

+			Result<Void> rp = service.deletePerm(trans,rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_PERMISSION);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deletePerm(AuthzTrans trans, HttpServletResponse resp, String type, String instance, String action) {

+		TimeTaken tt = trans.start(DELETE_PERMISSION + type + ' ' + instance + ' ' + action, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.deletePerm(trans,type,instance,action);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_PERMISSION);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	public static final String CREATE_ROLE = "createRole";

+	public static final String GET_ROLES_BY_USER = "getRolesByUser";

+	public static final String GET_ROLES_BY_NS = "getRolesByNS";

+	public static final String GET_ROLES_BY_NAME_ONLY = "getRolesByNameOnly";

+	public static final String GET_ROLES_BY_NAME = "getRolesByName";

+	public static final String GET_ROLES_BY_PERM = "getRolesByPerm";

+	public static final String UPDATE_ROLE_DESC = "updateRoleDescription"; 

+	public static final String ADD_PERM_TO_ROLE = "addPermissionToRole";

+	public static final String DELETE_PERM_FROM_ROLE = "deletePermissionFromRole";

+	public static final String UPDATE_MGTPERM_ROLE = "updateMgtPermRole";

+	public static final String DELETE_ROLE = "deleteRole";

+	public static final String GET_CERT_BY_ID = "getCertByID";

+

+	@Override

+	public Result<Void> createRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(CREATE_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = roleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_ROLE);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.createRole(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,roleRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,CREATE_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getRolesByName(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getRolesByName(AuthzTrans trans, HttpServletResponse resp, String role) {

+		TimeTaken tt = trans.start(GET_ROLES_BY_NAME + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<ROLES> rp = service.getRolesByName(trans, role);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<ROLES> data = roleDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,roleDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_ROLES_BY_NAME);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getRolesByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getRolesByUser(AuthzTrans trans,HttpServletResponse resp, String user) {

+		TimeTaken tt = trans.start(GET_ROLES_BY_USER + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<ROLES> rp = service.getRolesByUser(trans, user);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<ROLES> data = roleDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,roleDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_ROLES_BY_USER, user);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getRolesByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getRolesByNS(AuthzTrans trans,HttpServletResponse resp, String ns) {

+		TimeTaken tt = trans.start(GET_ROLES_BY_NS + ' ' + ns, Env.SUB|Env.ALWAYS);

+		try {

+			Result<ROLES> rp = service.getRolesByNS(trans, ns);

+			switch(rp.status) {

+				case OK: 

+					if(!rp.isEmpty()) {

+						RosettaData<ROLES> data = roleDF.newData(trans).load(rp.value);

+						if(Question.willSpecialLog(trans, trans.user())) {

+							Question.logEncryptTrace(trans,data.asString());

+						}

+						data.to(resp.getOutputStream());

+					} else {

+						Question.logEncryptTrace(trans, NO_DATA);

+					}

+					setContentType(resp,roleDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_ROLES_BY_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getRolesByNameOnly(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getRolesByNameOnly(AuthzTrans trans,HttpServletResponse resp, String nameOnly) {

+		TimeTaken tt = trans.start(GET_ROLES_BY_NAME_ONLY + ' ' + nameOnly, Env.SUB|Env.ALWAYS);

+		try {

+			Result<ROLES> rp = service.getRolesByNameOnly(trans, nameOnly);

+			switch(rp.status) {

+				case OK: 

+					if(!rp.isEmpty()) {

+						RosettaData<ROLES> data = roleDF.newData(trans).load(rp.value);

+						if(Question.willSpecialLog(trans, trans.user())) {

+							Question.logEncryptTrace(trans,data.asString());

+						}

+						data.to(resp.getOutputStream());

+					} else {

+						Question.logEncryptTrace(trans, NO_DATA);

+					}

+					setContentType(resp,roleDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_ROLES_BY_NAME_ONLY);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getRolesByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getRolesByPerm(AuthzTrans trans,HttpServletResponse resp, String type, String instance, String action) {

+		TimeTaken tt = trans.start(GET_ROLES_BY_PERM + type +' '+instance+' '+action, Env.SUB|Env.ALWAYS);

+		try {

+			Result<ROLES> rp = service.getRolesByPerm(trans, type,instance,action);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<ROLES> data = roleDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,roleDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_ROLES_BY_PERM);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#updateDescription(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

+	 */

+	@Override

+	public Result<Void> updateRoleDescription(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_ROLE_DESC, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = roleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,UPDATE_ROLE_DESC);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.updateRoleDescription(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,roleRequestDF.getOutType());

+					return Result.ok();

+				default:

+					return rp;

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_ROLE_DESC);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> addPermToRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(ADD_PERM_TO_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = rolePermRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,ADD_PERM_TO_ROLE);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.addPermToRole(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,ADD_PERM_TO_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> delPermFromRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DELETE_PERM_FROM_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = rolePermRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,DELETE_PERM_FROM_ROLE);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+

+			}

+			Result<Void> rp = service.delPermFromRole(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					resp.getOutputStream().println();

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_PERM_FROM_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deleteRole(AuthzTrans trans, HttpServletResponse resp, String role) {

+		TimeTaken tt = trans.start(DELETE_ROLE + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.deleteRole(trans, role);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deleteRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DELETE_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = roleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN,CREATE_ROLE);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+

+			Result<Void> rp = service.deleteRole(trans, rreq);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	public static final String CREATE_CRED = "createUserCred";

+	private static final String GET_CREDS_BY_NS = "getCredsByNS";

+	private static final String GET_CREDS_BY_ID = "getCredsByID";

+	public static final String UPDATE_CRED = "updateUserCred";

+	public static final String EXTEND_CRED = "extendUserCred";

+	public static final String DELETE_CRED = "deleteUserCred";

+	public static final String DOES_CRED_MATCH = "doesCredMatch";

+	public static final String VALIDATE_BASIC_AUTH = "validateBasicAuth";

+

+

+

+	@Override

+	/**

+	 * Create Credential

+	 * 

+	 */

+	public Result<Void> createUserCred(AuthzTrans trans, HttpServletRequest req) {

+		TimeTaken tt = trans.start(CREATE_CRED, Env.SUB|Env.ALWAYS);

+		try {

+			RosettaData<REQUEST> data = credRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+			return service.createUserCred(trans, data.asObject());

+		} catch(APIException e) {

+			trans.error().log(e,"Bad Input data");

+			return Result.err(Status.ERR_BadData, e.getLocalizedMessage());

+		} catch (Exception e) {

+			trans.error().log(e,IN,CREATE_CRED);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> changeUserCred(AuthzTrans trans, HttpServletRequest req) {

+		TimeTaken tt = trans.start(UPDATE_CRED, Env.SUB|Env.ALWAYS);

+		try {

+			RosettaData<REQUEST> data = credRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.changeUserCred(trans, data.asObject());

+		} catch(APIException e) {

+			trans.error().log(e,"Bad Input data");

+			return Result.err(Status.ERR_BadData, e.getLocalizedMessage());

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_CRED);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#extendUserCred(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, int)

+	 */

+	@Override

+	public Result<Void> extendUserCred(AuthzTrans trans, HttpServletRequest req, String days) {

+		TimeTaken tt = trans.start(EXTEND_CRED, Env.SUB|Env.ALWAYS);

+		try {

+			RosettaData<REQUEST> data = credRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.extendUserCred(trans, data.asObject(), days);

+		} catch(APIException e) {

+			trans.error().log(e,"Bad Input data");

+			return Result.err(Status.ERR_BadData, e.getLocalizedMessage());

+		} catch (Exception e) {

+			trans.error().log(e,IN,EXTEND_CRED);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> getCredsByNS(AuthzTrans trans, HttpServletResponse resp, String ns) {

+		TimeTaken tt = trans.start(GET_CREDS_BY_NS + ' ' + ns, Env.SUB|Env.ALWAYS);

+		

+		try {

+			Result<USERS> ru = service.getCredsByNS(trans,ns);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERS> data = usersDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans,trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_CREDS_BY_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+		

+	}

+	

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getCredsByID(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getCredsByID(AuthzTrans trans, HttpServletResponse resp, String id) {

+		TimeTaken tt = trans.start(GET_CREDS_BY_ID + ' ' + id, Env.SUB|Env.ALWAYS);

+		

+		try {

+			Result<USERS> ru = service.getCredsByID(trans,id);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERS> data = usersDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_CREDS_BY_ID);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+		

+	}

+

+	@Override

+	public Result<Void> deleteUserCred(AuthzTrans trans, HttpServletRequest req) {

+		TimeTaken tt = trans.start(DELETE_CRED, Env.SUB|Env.ALWAYS);

+		try {

+			RosettaData<REQUEST> data = credRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.deleteUserCred(trans, data.asObject());

+		} catch(APIException e) {

+			trans.error().log(e,"Bad Input data");

+			return Result.err(Status.ERR_BadData, e.getLocalizedMessage());

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_CRED);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}	

+	}

+	

+	

+	@Override

+	public Result<Date> doesCredentialMatch(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DOES_CRED_MATCH, Env.SUB|Env.ALWAYS);

+		try {

+			RosettaData<REQUEST> data = credRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.doesCredentialMatch(trans, data.asObject());

+		} catch(APIException e) {

+			trans.error().log(e,"Bad Input data");

+			return Result.err(Status.ERR_BadData, e.getLocalizedMessage());

+		} catch (IOException e) {

+			trans.error().log(e,IN,DOES_CRED_MATCH);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}	

+	}

+

+

+	@Override

+	public Result<Void> validBasicAuth(AuthzTrans trans, HttpServletResponse resp, String basicAuth) {

+		TimeTaken tt = trans.start(VALIDATE_BASIC_AUTH, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Date> result = service.validateBasicAuth(trans,basicAuth);

+			switch(result.status){

+				case OK:

+					resp.getOutputStream().write(Chrono.utcStamp(result.value).getBytes());

+					return Result.ok();

+			}

+			return Result.err(result);

+		} catch (Exception e) {

+			trans.error().log(e,IN,VALIDATE_BASIC_AUTH);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getCertInfoByID(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getCertInfoByID(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp, String id) {

+		TimeTaken tt = trans.start(GET_CERT_BY_ID, Env.SUB|Env.ALWAYS);

+		try {	

+			Result<CERTS> rci = service.getCertInfoByID(trans,req,id);

+			

+			switch(rci.status) {

+				case OK: 

+					if(Question.willSpecialLog(trans, trans.user())) {

+						RosettaData<CERTS> data = certsDF.newData(trans).load(rci.value);

+						Question.logEncryptTrace(trans,data.asString());

+						data.to(resp.getOutputStream());

+					} else {

+						certsDF.direct(trans, rci.value, resp.getOutputStream());

+					}

+					setContentType(resp,certsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rci);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_CERT_BY_ID);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	public static final String CREATE_DELEGATE = "createDelegate";

+	public static final String UPDATE_DELEGATE = "updateDelegate";

+	public static final String DELETE_DELEGATE = "deleteDelegate";

+	public static final String GET_DELEGATE_USER = "getDelegatesByUser";

+	public static final String GET_DELEGATE_DELG = "getDelegatesByDelegate";

+	

+	@Override

+	public Result<Void> createDelegate(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(CREATE_DELEGATE, Env.SUB|Env.ALWAYS);

+		try {	

+			Data<REQUEST> data = delgRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.createDelegate(trans, data.asObject());

+		} catch (Exception e) {

+			trans.error().log(e,IN,CREATE_DELEGATE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> updateDelegate(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_DELEGATE, Env.SUB|Env.ALWAYS);

+		try {	

+			Data<REQUEST> data = delgRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.updateDelegate(trans, data.asObject());

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_DELEGATE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> deleteDelegate(AuthzTrans trans,  HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(DELETE_DELEGATE, Env.SUB|Env.ALWAYS);

+		try {

+			Data<REQUEST> data = delgRequestDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			return service.deleteDelegate(trans, data.asObject());

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_DELEGATE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> deleteDelegate(AuthzTrans trans, String userName) {

+		TimeTaken tt = trans.start(DELETE_DELEGATE + ' ' + userName, Env.SUB|Env.ALWAYS);

+		try {

+			return service.deleteDelegate(trans, userName);

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_DELEGATE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> getDelegatesByUser(AuthzTrans trans, String user, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(GET_DELEGATE_USER, Env.SUB|Env.ALWAYS);

+		try {

+			Result<DELGS> rd = service.getDelegatesByUser(trans, user);

+			

+			switch(rd.status) {

+				case OK: 

+					RosettaData<DELGS> data = delgDF.newData(trans).load(rd.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,delgDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rd);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_DELEGATE_USER);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> getDelegatesByDelegate(AuthzTrans trans, String delegate, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(GET_DELEGATE_DELG, Env.SUB|Env.ALWAYS);

+		try {

+			Result<DELGS> rd = service.getDelegatesByDelegate(trans, delegate);

+			switch(rd.status) {

+				case OK: 

+					RosettaData<DELGS> data = delgDF.newData(trans).load(rd.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					setContentType(resp,delgDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rd);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_DELEGATE_DELG);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	private static final String REQUEST_USER_ROLE = "createUserRole";

+	private static final String GET_USERROLES = "getUserRoles";

+	private static final String GET_USERROLES_BY_ROLE = "getUserRolesByRole";

+	private static final String GET_USERROLES_BY_USER = "getUserRolesByUser";

+	private static final String SET_ROLES_FOR_USER = "setRolesForUser";

+	private static final String SET_USERS_FOR_ROLE = "setUsersForRole";

+	private static final String EXTEND_USER_ROLE = "extendUserRole";

+	private static final String DELETE_USER_ROLE = "deleteUserRole";

+	@Override

+	public Result<Void> requestUserRole(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(REQUEST_USER_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST request;

+			try {

+				Data<REQUEST> data = userRoleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+

+				request = data.asObject();

+			} catch(APIException e) {

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.createUserRole(trans,request);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,REQUEST_USER_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> getUserInRole(AuthzTrans trans, HttpServletResponse resp, String user, String role) {

+		TimeTaken tt = trans.start(GET_USERROLES + ' ' + user + '|' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<USERS> ru = service.getUserInRole(trans,user,role);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERS> data = usersDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_USERROLES);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+

+	}

+

+	@Override

+	public Result<Void> getUserRolesByUser(AuthzTrans trans, HttpServletResponse resp, String user) {

+		TimeTaken tt = trans.start(GET_USERROLES_BY_USER + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<USERROLES> ru = service.getUserRolesByUser(trans,user);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERROLES> data = userrolesDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_USERROLES_BY_USER);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+

+	}

+	

+	@Override

+	public Result<Void> getUserRolesByRole(AuthzTrans trans, HttpServletResponse resp, String role) {

+		TimeTaken tt = trans.start(GET_USERROLES_BY_ROLE + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<USERROLES> ru = service.getUserRolesByRole(trans,role);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERROLES> data = userrolesDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_USERROLES_BY_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+

+	}

+	

+

+	@Override

+	public Result<Void> resetUsersForRole(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req) {

+		TimeTaken tt = trans.start(SET_USERS_FOR_ROLE, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = userRoleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN, SET_USERS_FOR_ROLE);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.resetUsersForRole(trans, rreq);

+			

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,SET_USERS_FOR_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+		

+	}

+

+	@Override

+	public Result<Void> resetRolesForUser(AuthzTrans trans, HttpServletResponse resp, HttpServletRequest req) {

+		TimeTaken tt = trans.start(SET_ROLES_FOR_USER, Env.SUB|Env.ALWAYS);

+		try {

+			REQUEST rreq;

+			try {

+				RosettaData<REQUEST> data = userRoleRequestDF.newData().load(req.getInputStream());

+				if(Question.willSpecialLog(trans, trans.user())) {

+					Question.logEncryptTrace(trans,data.asString());

+				}

+

+				rreq = data.asObject();

+			} catch(APIException e) {

+				trans.error().log("Invalid Input",IN, SET_ROLES_FOR_USER);

+				return Result.err(Status.ERR_BadData,"Invalid Input");

+			}

+			

+			Result<Void> rp = service.resetRolesForUser(trans, rreq);

+			

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,SET_ROLES_FOR_USER);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+		

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#extendUserRoleExpiration(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> extendUserRoleExpiration(AuthzTrans trans, HttpServletResponse resp, String user, String role) {

+		TimeTaken tt = trans.start(EXTEND_USER_ROLE + ' ' + user + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			return service.extendUserRole(trans,user,role);

+		} catch (Exception e) {

+			trans.error().log(e,IN,EXTEND_USER_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> deleteUserRole(AuthzTrans trans, HttpServletResponse resp, String user, String role) {

+		TimeTaken tt = trans.start(DELETE_USER_ROLE + ' ' + user + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<Void> rp = service.deleteUserRole(trans,user,role);

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,DELETE_USER_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	private static final String UPDATE_APPROVAL = "updateApproval";

+	private static final String GET_APPROVALS_BY_USER = "getApprovalsByUser.";

+	private static final String GET_APPROVALS_BY_TICKET = "getApprovalsByTicket.";

+	private static final String GET_APPROVALS_BY_APPROVER = "getApprovalsByApprover.";

+	

+	@Override

+	public Result<Void> updateApproval(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) {

+		TimeTaken tt = trans.start(UPDATE_APPROVAL, Env.SUB|Env.ALWAYS);

+		try {

+			Data<APPROVALS> data = approvalDF.newData().load(req.getInputStream());

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			Result<Void> rp = service.updateApproval(trans, data.asObject());

+			

+			switch(rp.status) {

+				case OK: 

+					setContentType(resp,approvalDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,UPDATE_APPROVAL);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@Override

+	public Result<Void> getApprovalsByUser(AuthzTrans trans, HttpServletResponse resp, String user) {

+		TimeTaken tt = trans.start(GET_APPROVALS_BY_USER + ' ' + user, Env.SUB|Env.ALWAYS);

+		try {

+			Result<APPROVALS> rp = service.getApprovalsByUser(trans, user);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<APPROVALS> data = approvalDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+					data.to(resp.getOutputStream());

+					

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_APPROVALS_BY_USER, user);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> getApprovalsByApprover(AuthzTrans trans, HttpServletResponse resp, String approver) {

+		TimeTaken tt = trans.start(GET_APPROVALS_BY_APPROVER + ' ' + approver, Env.SUB|Env.ALWAYS);

+		try {

+			Result<APPROVALS> rp = service.getApprovalsByApprover(trans, approver);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<APPROVALS> data = approvalDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_APPROVALS_BY_APPROVER,approver);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	@Override

+	public Result<Void> getApprovalsByTicket(AuthzTrans trans, HttpServletResponse resp, String ticket) {

+		TimeTaken tt = trans.start(GET_APPROVALS_BY_TICKET, Env.SUB|Env.ALWAYS);

+		try {

+			Result<APPROVALS> rp = service.getApprovalsByTicket(trans, ticket);

+			switch(rp.status) {

+				case OK: 

+					RosettaData<APPROVALS> data = approvalDF.newData(trans).load(rp.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,permsDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rp);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_APPROVALS_BY_TICKET);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+

+	

+	public static final String GET_USERS_PERMISSION = "getUsersByPermission";

+	public static final String GET_USERS_ROLE = "getUsersByRole";

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getUsersByRole(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getUsersByRole(AuthzTrans trans, HttpServletResponse resp, String role) {

+		TimeTaken tt = trans.start(GET_USERS_ROLE + ' ' + role, Env.SUB|Env.ALWAYS);

+		try {

+			Result<USERS> ru = service.getUsersByRole(trans,role);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERS> data = usersDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_USERS_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getUsersByPermission(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getUsersByPermission(AuthzTrans trans, HttpServletResponse resp, 

+			String type, String instance, String action) {

+		TimeTaken tt = trans.start(GET_USERS_PERMISSION + ' ' + type + ' ' + instance + ' ' +action, Env.SUB|Env.ALWAYS);

+		try {

+			Result<USERS> ru = service.getUsersByPermission(trans,type,instance,action);

+			switch(ru.status) {

+				case OK: 

+					RosettaData<USERS> data = usersDF.newData(trans).load(ru.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,usersDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(ru);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_USERS_PERMISSION);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	

+	public static final String GET_HISTORY_USER = "getHistoryByUser";

+	public static final String GET_HISTORY_ROLE = "getHistoryByRole";

+	public static final String GET_HISTORY_PERM = "getHistoryByPerm";

+	public static final String GET_HISTORY_NS = "getHistoryByNS";

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getHistoryByUser(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)

+	 */

+	@Override

+	public Result<Void> getHistoryByUser(AuthzTrans trans, HttpServletResponse resp, String user, int[] yyyymm, final int sort) {

+		StringBuilder sb = new StringBuilder();

+		sb.append(GET_HISTORY_USER);

+		sb.append(' ');

+		sb.append(user);

+		sb.append(" for ");

+		boolean first = true;

+		for(int i : yyyymm) {

+			if(first) {

+			    first = false;

+			} else {

+			    sb.append(',');

+			}

+			sb.append(i);

+		}

+		TimeTaken tt = trans.start(sb.toString(), Env.SUB|Env.ALWAYS);

+

+		try {

+			Result<HISTORY> rh = service.getHistoryByUser(trans,user,yyyymm,sort);

+			switch(rh.status) {

+				case OK: 

+					RosettaData<HISTORY> data = historyDF.newData(trans).load(rh.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,historyDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rh);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_HISTORY_USER);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getHistoryByRole(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, int[])

+	 */

+	@Override

+	public Result<Void> getHistoryByRole(AuthzTrans trans, HttpServletResponse resp, String role, int[] yyyymm, final int sort) {

+		StringBuilder sb = new StringBuilder();

+		sb.append(GET_HISTORY_ROLE);

+		sb.append(' ');

+		sb.append(role);

+		sb.append(" for ");

+		boolean first = true;

+		for(int i : yyyymm) {

+			if(first) {

+			    first = false;

+			} else {

+			    sb.append(',');

+			}

+			sb.append(i);

+		}

+		TimeTaken tt = trans.start(sb.toString(), Env.SUB|Env.ALWAYS);

+		try {

+			Result<HISTORY> rh = service.getHistoryByRole(trans,role,yyyymm,sort);

+			switch(rh.status) {

+				case OK: 

+					RosettaData<HISTORY> data = historyDF.newData(trans).load(rh.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,historyDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rh);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_HISTORY_ROLE);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getHistoryByNS(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, int[])

+	 */

+	@Override

+	public Result<Void> getHistoryByNS(AuthzTrans trans, HttpServletResponse resp, String ns, int[] yyyymm, final int sort) {

+		StringBuilder sb = new StringBuilder();

+		sb.append(GET_HISTORY_NS);

+		sb.append(' ');

+		sb.append(ns);

+		sb.append(" for ");

+		boolean first = true;

+		for(int i : yyyymm) {

+			if(first) {

+			    first = false;

+			} else {

+			    sb.append(',');

+			}

+			sb.append(i);

+		}

+		TimeTaken tt = trans.start(sb.toString(), Env.SUB|Env.ALWAYS);

+		try {

+			Result<HISTORY> rh = service.getHistoryByNS(trans,ns,yyyymm,sort);

+			switch(rh.status) {

+				case OK: 

+					RosettaData<HISTORY> data = historyDF.newData(trans).load(rh.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,historyDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rh);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_HISTORY_NS);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getHistoryByPerm(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String, int[])

+	 */

+	@Override

+	public Result<Void> getHistoryByPerm(AuthzTrans trans, HttpServletResponse resp, String perm, int[] yyyymm, final int sort) {

+		StringBuilder sb = new StringBuilder();

+		sb.append(GET_HISTORY_PERM);

+		sb.append(' ');

+		sb.append(perm);

+		sb.append(" for ");

+		boolean first = true;

+		for(int i : yyyymm) {

+			if(first) {

+			    first = false;

+			} else {

+			    sb.append(',');

+			}

+			sb.append(i);

+		}

+		TimeTaken tt = trans.start(sb.toString(), Env.SUB|Env.ALWAYS);

+		try {

+			Result<HISTORY> rh = service.getHistoryByPerm(trans,perm,yyyymm,sort);

+			switch(rh.status) {

+				case OK: 

+					RosettaData<HISTORY> data = historyDF.newData(trans).load(rh.value);

+					if(Question.willSpecialLog(trans, trans.user())) {

+						Question.logEncryptTrace(trans,data.asString());

+					}

+

+					data.to(resp.getOutputStream());

+					setContentType(resp,historyDF.getOutType());

+					return Result.ok();

+				default:

+					return Result.err(rh);

+			}

+		} catch (Exception e) {

+			trans.error().log(e,IN,GET_HISTORY_PERM);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	public final static String CACHE_CLEAR = "cacheClear "; 

+//	public final static String CACHE_VALIDATE = "validateCache";

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#cacheClear(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+	@Override

+	public Result<Void> cacheClear(AuthzTrans trans, String cname) {

+		TimeTaken tt = trans.start(CACHE_CLEAR + cname, Env.SUB|Env.ALWAYS);

+		try {

+			return service.cacheClear(trans,cname);

+		} catch (Exception e) {

+			trans.error().log(e,IN,CACHE_CLEAR);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+ * @see org.onap.aaf.authz.facade.AuthzFacade#cacheClear(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.Integer)

+ */

+	@Override

+	public Result<Void> cacheClear(AuthzTrans trans, String cname,	String segments) {

+		TimeTaken tt = trans.start(CACHE_CLEAR + cname + ", segments[" + segments + ']', Env.SUB|Env.ALWAYS);

+		try {

+			String[] segs = segments.split("\\s*,\\s*");

+			int isegs[] = new int[segs.length];

+			for(int i=0;i<segs.length;++i) {

+				try {

+					isegs[i] = Integer.parseInt(segs[i]);

+				} catch(NumberFormatException nfe) {

+					isegs[i] = -1;

+				}

+			}

+			return service.cacheClear(trans,cname, isegs);

+		} catch (Exception e) {

+			trans.error().log(e,IN,CACHE_CLEAR);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#dbReset(org.onap.aaf.authz.env.AuthzTrans)

+	 */

+	@Override

+	public void dbReset(AuthzTrans trans) {

+		service.dbReset(trans);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getAPI(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse)

+	 */

+	public final static String API_REPORT = "apiReport";

+	@Override

+	public Result<Void> getAPI(AuthzTrans trans, HttpServletResponse resp, RServlet<AuthzTrans> rservlet) {

+		TimeTaken tt = trans.start(API_REPORT, Env.SUB);

+		try {

+			Api api = new Api();

+			Api.Route ar;

+			Method[] meths = AuthzCassServiceImpl.class.getDeclaredMethods();

+			for(RouteReport rr : rservlet.routeReport()) {

+				api.getRoute().add(ar = new Api.Route());

+				ar.setMeth(rr.meth.name());

+				ar.setPath(rr.path);

+				ar.setDesc(rr.desc);

+				ar.getContentType().addAll(rr.contextTypes);

+				for(Method m : meths) {

+					ApiDoc ad;

+					if((ad = m.getAnnotation(ApiDoc.class))!=null &&

+							rr.meth.equals(ad.method()) &&

+						    rr.path.equals(ad.path())) {

+						for(String param : ad.params()) {

+							ar.getParam().add(param);

+						}

+						for(String text : ad.text()) {

+							ar.getComments().add(text);

+						}

+						ar.setExpected(ad.expectedCode());

+						for(int ec : ad.errorCodes()) {

+							ar.getExplicitErr().add(ec);

+						}

+					}

+				}

+			}

+			RosettaData<Api> data = apiDF.newData(trans).load(api);

+			if(Question.willSpecialLog(trans, trans.user())) {

+				Question.logEncryptTrace(trans,data.asString());

+			}

+

+			data.to(resp.getOutputStream());

+			setContentType(resp,apiDF.getOutType());

+			return Result.ok();

+

+		} catch (Exception e) {

+			trans.error().log(e,IN,API_REPORT);

+			return Result.err(e);

+		} finally {

+			tt.done();

+		}

+	}

+	

+

+	public final static String API_EXAMPLE = "apiExample";

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.facade.AuthzFacade#getAPIExample(org.onap.aaf.authz.env.AuthzTrans, javax.servlet.http.HttpServletResponse, java.lang.String)

+	 */

+	@Override

+	public Result<Void> getAPIExample(AuthzTrans trans, HttpServletResponse resp, String nameOrContentType, boolean optional) {

+		TimeTaken tt = trans.start(API_EXAMPLE, Env.SUB);

+		try {

+			String content =Examples.print(apiDF.getEnv(), nameOrContentType, optional); 

+			resp.getOutputStream().print(content);

+			setContentType(resp,content.contains("<?xml")?TYPE.XML:TYPE.JSON);

+			return Result.ok();

+		} catch (Exception e) {

+			trans.error().log(e,IN,API_EXAMPLE);

+			return Result.err(Status.ERR_NotImplemented,e.getMessage());

+		} finally {

+			tt.done();

+		}

+	}

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade_2_0.java b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade_2_0.java
new file mode 100644
index 0000000..fae128c
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/facade/AuthzFacade_2_0.java
@@ -0,0 +1,65 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.facade;

+

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.service.AuthzService;

+

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+

+import aaf.v2_0.Approvals;

+import aaf.v2_0.Certs;

+import aaf.v2_0.Delgs;

+import aaf.v2_0.Error;

+import aaf.v2_0.History;

+import aaf.v2_0.Keys;

+import aaf.v2_0.Nss;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Pkey;

+import aaf.v2_0.Request;

+import aaf.v2_0.Roles;

+import aaf.v2_0.UserRoles;

+import aaf.v2_0.Users;

+

+public class AuthzFacade_2_0 extends AuthzFacadeImpl<

+	Nss,

+	Perms,

+	Pkey,

+	Roles,

+	Users,

+	UserRoles,

+	Delgs,

+	Certs,

+	Keys,

+	Request,

+	History,

+	Error,

+	Approvals>

+{

+	public AuthzFacade_2_0(AuthzEnv env,

+			AuthzService<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals> service,

+			Data.TYPE type) throws APIException {

+		super(env, service, type);

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/AuthAPI.java b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthAPI.java
new file mode 100644
index 0000000..3a91807
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthAPI.java
@@ -0,0 +1,330 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import java.io.IOException;

+import java.net.HttpURLConnection;

+import java.security.GeneralSecurityException;

+import java.util.ArrayList;

+import java.util.EnumSet;

+import java.util.List;

+import java.util.Properties;

+

+import org.onap.aaf.authz.cadi.DirectAAFLur;

+import org.onap.aaf.authz.cadi.DirectAAFUserPass;

+import org.onap.aaf.authz.cadi.DirectCertIdentity;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.env.AuthzTransFilter;

+import org.onap.aaf.authz.facade.AuthzFacadeFactory;

+import org.onap.aaf.authz.facade.AuthzFacade_2_0;

+import org.onap.aaf.authz.org.OrganizationFactory;

+import org.onap.aaf.authz.server.AbsServer;

+import org.onap.aaf.authz.service.api.API_Api;

+import org.onap.aaf.authz.service.api.API_Approval;

+import org.onap.aaf.authz.service.api.API_Creds;

+import org.onap.aaf.authz.service.api.API_Delegate;

+import org.onap.aaf.authz.service.api.API_History;

+import org.onap.aaf.authz.service.api.API_Mgmt;

+import org.onap.aaf.authz.service.api.API_NS;

+import org.onap.aaf.authz.service.api.API_Perms;

+import org.onap.aaf.authz.service.api.API_Roles;

+import org.onap.aaf.authz.service.api.API_User;

+import org.onap.aaf.authz.service.api.API_UserRole;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+import org.onap.aaf.dao.CassAccess;

+import org.onap.aaf.dao.aaf.cass.CacheInfoDAO;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+import com.att.aft.dme2.api.DME2Exception;

+//import com.att.aft.dme2.api.DME2FilterHolder;

+//import com.att.aft.dme2.api.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.DME2Manager;

+import com.att.aft.dme2.api.DME2Server;

+import com.att.aft.dme2.api.DME2ServerProperties;

+import com.att.aft.dme2.api.DME2ServiceHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder;

+import com.att.aft.dme2.api.util.DME2FilterHolder.RequestDispatcherType;

+import com.att.aft.dme2.api.util.DME2ServletHolder;

+import org.onap.aaf.cadi.CadiException;

+import org.onap.aaf.cadi.LocatorException;

+import org.onap.aaf.cadi.SecuritySetter;

+import org.onap.aaf.cadi.aaf.v2_0.AAFTrustChecker;

+import org.onap.aaf.cadi.config.Config;

+import org.onap.aaf.cadi.config.SecurityInfoC;

+import org.onap.aaf.cadi.http.HBasicAuthSS;

+import org.onap.aaf.cadi.http.HMangr;

+import org.onap.aaf.cadi.http.HX509SS;

+import org.onap.aaf.cadi.locator.DME2Locator;

+import org.onap.aaf.cadi.taf.basic.BasicHttpTaf;

+import org.onap.aaf.inno.env.APIException;

+import org.onap.aaf.inno.env.Data;

+import org.onap.aaf.inno.env.Env;

+import com.datastax.driver.core.Cluster;

+

+public class AuthAPI extends AbsServer {

+

+	private static final String ORGANIZATION = "Organization.";

+	private static final String DOMAIN = "openecomp.org";

+

+// TODO Add Service Metrics

+//	private Metric serviceMetric;

+	public final Question question;

+//	private final SessionFilter sessionFilter;

+	private AuthzFacade_2_0 facade;

+	private AuthzFacade_2_0 facade_XML;

+	private DirectAAFUserPass directAAFUserPass;

+	

+	/**

+	 * Construct AuthzAPI with all the Context Supporting Routes that Authz needs

+	 * 

+	 * @param env

+	 * @param decryptor 

+	 * @throws APIException 

+	 */

+	public AuthAPI(AuthzEnv env) throws Exception {

+		super(env,"AAF");

+	

+		// Set "aaf_url" for peer communication based on Service DME2 URL

+		env.setProperty(Config.AAF_URL, "https://DME2RESOLVE/"+env.getProperty("DMEServiceName"));

+		

+		// Setup Log Names

+		env.setLog4JNames("log4j.properties","authz","authz|service","audit","init","trace");

+

+		final Cluster cluster = org.onap.aaf.dao.CassAccess.cluster(env,null);

+

+		// jg 4/2015 SessionFilter unneeded... DataStax already deals with Multithreading well

+		

+		// Setup Shutdown Hooks for Cluster and Pooled Sessions

+		Runtime.getRuntime().addShutdownHook(new Thread() {

+			@Override

+			public void run() {

+//				sessionFilter.destroy();

+				cluster.close();

+			}

+		}); 

+		

+		// Initialize Facade for all uses

+		AuthzTrans trans = env.newTrans();

+

+		// Initialize Organizations... otherwise, first pass may miss

+		int org_size = ORGANIZATION.length();

+		for(String n : env.existingStaticSlotNames()) {

+			if(n.startsWith(ORGANIZATION)) {

+				OrganizationFactory.obtain(env, n.substring(org_size));

+			}

+		}

+		

+		// Need Question for Security purposes (direct User/Authz Query in Filter)

+		// Start Background Processing

+		question = new Question(trans, cluster, CassAccess.KEYSPACE, true);

+		

+		DirectCertIdentity.set(question.certDAO);

+		

+		facade = AuthzFacadeFactory.v2_0(env,trans,Data.TYPE.JSON,question);

+		facade_XML = AuthzFacadeFactory.v2_0(env,trans,Data.TYPE.XML,question);

+

+		directAAFUserPass = new DirectAAFUserPass(

+    			trans.env(),question,trans.getProperty("Unknown"));

+

+		

+		// Print results and cleanup

+		StringBuilder sb = new StringBuilder();

+		trans.auditTrail(0, sb);

+		if(sb.length()>0)env.init().log(sb);

+		trans = null;

+		sb = null;

+

+		////////////////////////////////////////////////////////////////////////////

+		// Time Critical

+		//  These will always be evaluated first

+		////////////////////////////////////////////////////////////////////////

+		API_Creds.timeSensitiveInit(env, this, facade,directAAFUserPass);

+		API_Perms.timeSensitiveInit(this, facade);

+		////////////////////////////////////////////////////////////////////////

+		// Service APIs

+		////////////////////////////////////////////////////////////////////////

+		API_Creds.init(this, facade);

+		API_UserRole.init(this, facade);

+		API_Roles.init(this, facade);

+		API_Perms.init(this, facade);

+		API_NS.init(this, facade);

+		API_User.init(this, facade);

+		API_Delegate.init(this,facade);

+		API_Approval.init(this, facade);

+		API_History.init(this, facade);

+

+		////////////////////////////////////////////////////////////////////////

+		// Management APIs

+		////////////////////////////////////////////////////////////////////////

+		// There are several APIs around each concept, and it gets a bit too

+		// long in this class to create.  The initialization of these Management

+		// APIs have therefore been pushed to StandAlone Classes with static

+		// init functions

+		API_Mgmt.init(this, facade);

+		API_Api.init(this, facade);

+		

+	}

+	

+	/**

+	 * Setup XML and JSON implementations for each supported Version type

+	 * 

+	 * We do this by taking the Code passed in and creating clones of these with the appropriate Facades and properties

+	 * to do Versions and Content switches

+	 * 

+	 */

+	public void route(HttpMethods meth, String path, API api, Code code) throws Exception {

+		String version = "2.0";

+		Class<?> respCls = facade.mapper().getClass(api); 

+		if(respCls==null) throw new Exception("Unknown class associated with " + api.getClass().getName() + ' ' + api.name());

+		String application = applicationJSON(respCls, version);

+

+		route(env,meth,path,code,application,"application/json;version=2.0","*/*");

+		application = applicationXML(respCls, version);

+		route(env,meth,path,code.clone(facade_XML,false),application,"text/xml;version=2.0");

+	}

+

+	/**

+	 * Start up AuthzAPI as DME2 Service

+	 * @param env

+	 * @param props

+	 * @throws Exception 

+	 * @throws LocatorException 

+	 * @throws CadiException 

+	 * @throws NumberFormatException 

+	 * @throws IOException 

+	 * @throws GeneralSecurityException 

+	 * @throws APIException 

+	 */

+	public void startDME2(Properties props) throws Exception {

+        DME2Manager dme2 = new DME2Manager("AuthzServiceDME2Manager",props);

+       	String s = dme2.getStringProp(Config.AFT_DME2_SSL_INCLUDE_PROTOCOLS,null);

+       	env.init().log("DME2 Service TLS Protocols are set to",(s==null?"DME2 Default":s));

+        

+        DME2ServiceHolder svcHolder;

+        List<DME2ServletHolder> slist = new ArrayList<DME2ServletHolder>();

+        svcHolder = new DME2ServiceHolder();

+        String serviceName = env.getProperty("DMEServiceName",null);

+    	if(serviceName!=null) {

+	    	svcHolder.setServiceURI(serviceName);

+	        svcHolder.setManager(dme2);

+	        svcHolder.setContext("/");

+	        DME2ServletHolder srvHolder = new DME2ServletHolder(this, new String[]{"/authz","/authn","/mgmt"});

+	        srvHolder.setContextPath("/*");

+	        slist.add(srvHolder);

+	        

+	        EnumSet<RequestDispatcherType> edlist = EnumSet.of(

+	        		RequestDispatcherType.REQUEST,

+	        		RequestDispatcherType.FORWARD,

+	        		RequestDispatcherType.ASYNC

+	        		);

+	        

+	        List<DME2FilterHolder> flist = new ArrayList<DME2FilterHolder>();

+

+	        // Add DME2 Metrics

+	        // DME2 removed the Metrics Filter in 2.8.8.5

+        	// flist.add(new DME2FilterHolder(new DME2MetricsFilter(serviceName),"/*",edlist));

+	        

+	        // Note: Need CADI to fill out User for AuthTransFilter... so it's first

+    		// Make sure there is no AAF TAF configured for Filters

+    		env.setProperty(Config.AAF_URL,null);

+

+	        flist.add(

+		        new DME2FilterHolder(

+		        	new AuthzTransFilter(env, null /* no connection to AAF... it is AAF */,

+	        			new AAFTrustChecker((Env)env),

+	        	        new DirectAAFLur(env,question), // Note, this will be assigned by AuthzTransFilter to TrustChecker

+	        	        new BasicHttpTaf(env, directAAFUserPass,

+		        			DOMAIN,Long.parseLong(env.getProperty(Config.AAF_CLEAN_INTERVAL, Config.AAF_CLEAN_INTERVAL_DEF)),

+		        			false

+		        			) // Add specialty Direct TAF

+		        		),

+		        	"/*", edlist));

+

+	        svcHolder.setFilters(flist);

+	        svcHolder.setServletHolders(slist);

+	        

+	        DME2Server dme2svr = dme2.getServer();

+	        

+	        String hostname = env.getProperty("HOSTNAME",null);

+	        if(hostname!=null) {

+	        	//dme2svr.setHostname(hostname);

+	        	hostname=null;

+	        }

+	       // dme2svr.setGracefulShutdownTimeMs(5000);

+	

+	        env.init().log("Starting AAF Jetty/DME2 server...");

+	        dme2svr.start();

+	        try {

+//	        	if(env.getProperty("NO_REGISTER",null)!=null)

+	        	dme2.bindService(svcHolder);

+	        	//env.init().log("DME2 is available as HTTPS on port:",dme2svr.getPort());

+	        	

+	        	// Start CacheInfo Listener

+	        	HMangr hman = new HMangr(env, new DME2Locator(env, dme2,"https://DME2RESOLVE/"+serviceName,true /*remove self from cache*/));

+				SecuritySetter<HttpURLConnection> ss;

+				

+//				InetAddress ip = InetAddress.getByName(dme2svr.getHostname());

+				SecurityInfoC<HttpURLConnection> si = new SecurityInfoC<HttpURLConnection>(env);

+				String mechID;

+				if((mechID=env.getProperty(Config.AAF_MECHID))==null) {

+					String alias = env.getProperty(Config.CADI_ALIAS);

+					if(alias==null) {

+						env.init().log(Config.CADI_ALIAS, "is required for AAF Authentication by Certificate.  Alternately, set",Config.AAF_MECHID,"and",Config.AAF_MECHPASS);

+						System.exit(1);

+					}

+					ss = new HX509SS(alias,si,true);

+					env.init().log("X509 Certificate Client configured:", alias);

+				} else {

+					String pass = env.getProperty(Config.AAF_MECHPASS);

+					if(pass==null) {

+						env.init().log(Config.AAF_MECHPASS, "is required for AAF Authentication by ID/Pass");

+						System.exit(1);

+					}

+					ss = new HBasicAuthSS(mechID,env.decrypt(pass, true),si,true);

+					env.init().log("BasicAuth (ID/Pass) Client configured.");

+				}

+				

+				//TODO Reenable Cache Update

+	    		//CacheInfoDAO.startUpdate(env, hman, ss, dme2svr.getHostname(), dme2svr.getPort());

+	        	

+	            while(true) { // Per DME2 Examples...

+	            	Thread.sleep(5000);

+	            }

+	        } catch(DME2Exception e) { // Error binding service doesn't seem to stop DME2 or Process

+	            env.init().log(e,"DME2 Initialization Error");

+	        	dme2svr.stop();

+	        	System.exit(1);

+	        } catch(InterruptedException e) {

+	            env.init().log("AAF Jetty Server interrupted!");

+	        }

+    	} else {

+    		env.init().log("Properties must contain 'DMEServiceName'");

+    	}

+	}

+

+	public static void main(String[] args) {

+		setup(AuthAPI.class,"authAPI.props");

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzCassServiceImpl.java b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzCassServiceImpl.java
new file mode 100644
index 0000000..1388474
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzCassServiceImpl.java
@@ -0,0 +1,3973 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import java.io.IOException;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.HashMap;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.TreeMap;

+import java.util.UUID;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Executor;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.Organization.Expiration;

+import org.onap.aaf.authz.org.Organization.Identity;

+import org.onap.aaf.authz.org.Organization.Policy;

+import org.onap.aaf.authz.service.mapper.Mapper;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.authz.service.validation.Validator;

+import org.onap.aaf.cssa.rserv.doc.ApiDoc;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.FutureDAO;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.NsDAO;

+import org.onap.aaf.dao.aaf.cass.NsSplit;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.NsDAO.Data;

+import org.onap.aaf.dao.aaf.hl.CassExecutor;

+import org.onap.aaf.dao.aaf.hl.Function;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.onap.aaf.dao.aaf.hl.Question.Access;

+

+import org.onap.aaf.cadi.principal.BasicPrincipal;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.util.Chrono;

+import org.onap.aaf.inno.env.util.Split;

+

+import aaf.v2_0.CredRequest;

+

+/**

+ * AuthzCassServiceImpl implements AuthzCassService for 

+ * 

+ *

+ * @param <NSS>

+ * @param <PERMS>

+ * @param <PERMKEY>

+ * @param <ROLES>

+ * @param <USERS>

+ * @param <DELGS>

+ * @param <REQUEST>

+ * @param <HISTORY>

+ * @param <ERR>

+ * @param <APPROVALS>

+ */

+public class AuthzCassServiceImpl	<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS>

+	implements AuthzService			<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> {

+	

+	private Mapper					<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper;

+	@Override

+	public Mapper					<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper() {return mapper;}

+	

+	private static final String ASTERIX = "*";

+	private static final String CACHE = "cache";

+

+	private final Question ques;

+	private final Function func;

+	

+	public AuthzCassServiceImpl(AuthzTrans trans, Mapper<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper,Question question) {

+		this.ques = question;

+		func = new Function(trans, question);

+		this.mapper = mapper;

+		

+	}

+

+/***********************************

+ * NAMESPACE 

+ ***********************************/

+	/**

+	 * createNS

+	 * @throws DAOException 

+	 * @see org.onap.aaf.authz.service.AuthzService#createNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@ApiDoc( 

+			method = POST,  

+			path = "/authz/ns",

+			params = {},

+			expectedCode = 201,

+			errorCodes = { 403,404,406,409 }, 

+			text = { "Namespace consists of: ",

+					"<ul><li>name - What you want to call this Namespace</li>",

+					"<li>responsible(s) - Person(s) who receive Notifications and approves Requests ",

+					"regarding this Namespace. Companies have Policies as to who may take on ",

+					"this Responsibility. Separate multiple identities with commas</li>",

+					"<li>admin(s) - Person(s) who are allowed to make changes on the namespace, ",

+					"including creating Roles, Permissions and Credentials. Separate multiple ",

+					"identities with commas</li></ul>",

+					"Note: Namespaces are dot-delimited (i.e. com.myCompany.myApp) and must be ",

+					"created with parent credentials (i.e. To create com.myCompany.myApp, you must ",

+					"be an admin of com.myCompany or com"

+					}

+			)

+	@Override

+	public Result<Void> createNS(final AuthzTrans trans, REQUEST from, NsType type) {

+		final Result<Namespace> rnamespace = mapper.ns(trans, from);

+		final Validator v = new Validator();

+		if(v.ns(rnamespace).err()) { 

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		final Namespace namespace = rnamespace.value;

+		final Result<NsDAO.Data> parentNs = ques.deriveNs(trans,namespace.name);

+		if(parentNs.notOK()) {

+			return Result.err(parentNs);

+		}

+		

+		if(namespace.name.lastIndexOf('.')<0) { // Root Namespace... Function will check if allowed

+			return func.createNS(trans, namespace, false);

+		}

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans, NsDAO.TABLE,from,namespace,true, 

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Create Namespace [" + namespace.name + ']';

+					}

+				},

+				new MayChange() {

+					private Result<NsDAO.Data> rnd;

+					@Override

+					public Result<?> mayChange() {

+						if(rnd==null) {

+							rnd = ques.mayUser(trans, trans.user(), parentNs.value,Access.write);

+						}

+						return rnd;

+					}

+				});

+			switch(fd.status) {

+				case OK:

+					Result<List<Identity>> rfc = func.createFuture(trans, fd.value, namespace.name, trans.user(),parentNs.value, "C");

+					if(rfc.isOK()) {

+						return Result.err(Status.ACC_Future, "NS [%s] is saved for future processing",namespace.name);

+					} else { 

+						return Result.err(rfc);

+					}

+				case Status.ACC_Now:

+					return func.createNS(trans, namespace, false);

+				default:

+					return Result.err(fd);

+			}

+	}

+	

+	@ApiDoc(

+			method = POST,  

+			path = "/authz/ns/:ns/admin/:id",

+			params = { 	"ns|string|true",

+						"id|string|true" 

+					},

+			expectedCode = 201,

+			errorCodes = { 403,404,406,409 }, 

+			text = { 	"Add an Identity :id to the list of Admins for the Namespace :ns", 

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)" }

+			)

+	@Override

+	public Result<Void> addAdminNS(AuthzTrans trans, String ns, String id) {

+		return func.addUserRole(trans, id, ns,Question.ADMIN);

+	}

+

+	@ApiDoc(

+			method = DELETE,  

+			path = "/authz/ns/:ns/admin/:id",

+			params = { 	"ns|string|true",

+						"id|string|true" 

+					},

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Remove an Identity :id from the list of Admins for the Namespace :ns",

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)" }

+			)

+	@Override

+	public Result<Void> delAdminNS(AuthzTrans trans, String ns, String id) {

+		return func.delAdmin(trans,ns,id);

+	}

+

+	@ApiDoc(

+			method = POST,  

+			path = "/authz/ns/:ns/responsible/:id",

+			params = { 	"ns|string|true",

+						"id|string|true" 

+					},

+			expectedCode = 201,

+			errorCodes = { 403,404,406,409 }, 

+			text = { 	"Add an Identity :id to the list of Responsibles for the Namespace :ns",

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)" }

+			)

+	@Override

+	public Result<Void> addResponsibleNS(AuthzTrans trans, String ns, String id) {

+		return func.addUserRole(trans,id,ns,Question.OWNER);

+	}

+

+	@ApiDoc(

+			method = DELETE,  

+			path = "/authz/ns/:ns/responsible/:id",

+			params = { 	"ns|string|true",

+						"id|string|true" 

+					},

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Remove an Identity :id to the list of Responsibles for the Namespace :ns",

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)",

+						"Note: A namespace must have at least 1 responsible party"

+					}

+			)

+	@Override

+	public Result<Void> delResponsibleNS(AuthzTrans trans, String ns, String id) {

+		return func.delOwner(trans,ns,id);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#applyModel(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object)

+	 */

+	@ApiDoc(

+			method = POST,  

+			path = "/authz/ns/:ns/attrib/:key/:value",

+			params = { 	"ns|string|true",

+						"key|string|true",

+						"value|string|true"},

+			expectedCode = 201,

+			errorCodes = { 403,404,406,409 },  

+			text = { 	

+				"Create an attribute in the Namespace",

+				"You must be given direct permission for key by AAF"

+				}

+			)

+	@Override

+	public Result<Void> createNsAttrib(AuthzTrans trans, String ns, String key, String value) {

+		TimeTaken tt = trans.start("Create NsAttrib " + ns + ':' + key + ':' + value, Env.SUB);

+		try {

+			// Check inputs

+			final Validator v = new Validator();

+			if(v.ns(ns).err() ||

+			   v.key(key).err() ||

+			   v.value(value).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+

+			// Check if exists already

+			Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);

+			if(rlnsd.notOKorIsEmpty()) {

+				return Result.err(rlnsd);

+			}

+			NsDAO.Data nsd = rlnsd.value.get(0);

+

+			// Check for Existence

+			if(nsd.attrib.get(key)!=null) {

+				return Result.err(Status.ERR_ConflictAlreadyExists, "NS Property %s:%s exists", ns, key);

+			}

+			

+			// Check if User may put

+			if(!ques.isGranted(trans, trans.user(), Define.ROOT_NS, Question.ATTRIB, 

+					":"+trans.org().getDomain()+".*:"+key, Access.write.name())) {

+				return Result.err(Status.ERR_Denied, "%s may not create NS Attrib [%s:%s]", trans.user(),ns, key);

+			}

+

+			// Add Attrib

+			nsd.attrib.put(key, value);

+			ques.nsDAO.dao().attribAdd(trans,ns,key,value);

+			return Result.ok();

+		} finally {

+			tt.done();

+		}

+	}

+	

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/ns/attrib/:key",

+			params = { 	"key|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404 },  

+			text = { 	

+				"Read Attributes for Namespace"

+				}

+			)

+	@Override

+	public Result<KEYS> readNsByAttrib(AuthzTrans trans, String key) {

+		// Check inputs

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Key",key).err()) {

+			  return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		// May Read

+		if(!ques.isGranted(trans, trans.user(), Define.ROOT_NS, Question.ATTRIB, 

+					":"+trans.org().getDomain()+".*:"+key, Question.READ)) {

+			return Result.err(Status.ERR_Denied,"%s may not read NS by Attrib '%s'",trans.user(),key);

+		}

+

+		Result<Set<String>> rsd = ques.nsDAO.dao().readNsByAttrib(trans, key);

+		if(rsd.notOK()) {

+			return Result.err(rsd);

+		}

+		return mapper().keys(rsd.value);

+	}

+

+

+	@ApiDoc(

+			method = PUT,  

+			path = "/authz/ns/:ns/attrib/:key/:value",

+			params = { 	"ns|string|true",

+						"key|string|true"},

+			expectedCode = 200,

+			errorCodes = { 403,404 },  

+			text = { 	

+				"Update Value on an existing attribute in the Namespace",

+				"You must be given direct permission for key by AAF"

+				}

+			)

+	@Override

+	public Result<?> updateNsAttrib(AuthzTrans trans, String ns, String key, String value) {

+		TimeTaken tt = trans.start("Update NsAttrib " + ns + ':' + key + ':' + value, Env.SUB);

+		try {

+			// Check inputs

+			final Validator v = new Validator();

+			if(v.ns(ns).err() ||

+			   v.key(key).err() ||

+			   v.value(value).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+

+			// Check if exists already (NS must exist)

+			Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);

+			if(rlnsd.notOKorIsEmpty()) {

+				return Result.err(rlnsd);

+			}

+			NsDAO.Data nsd = rlnsd.value.get(0);

+

+			// Check for Existence

+			if(nsd.attrib.get(key)==null) {

+				return Result.err(Status.ERR_NotFound, "NS Property %s:%s exists", ns, key);

+			}

+			

+			// Check if User may put

+			if(!ques.isGranted(trans, trans.user(), Define.ROOT_NS, Question.ATTRIB, 

+					":"+trans.org().getDomain()+".*:"+key, Access.write.name())) {

+				return Result.err(Status.ERR_Denied, "%s may not create NS Attrib [%s:%s]", trans.user(),ns, key);

+			}

+

+			// Add Attrib

+			nsd.attrib.put(key, value);

+

+			return ques.nsDAO.update(trans,nsd);

+ 

+		} finally {

+			tt.done();

+		}

+	}

+

+	@ApiDoc(

+			method = DELETE,  

+			path = "/authz/ns/:ns/attrib/:key",

+			params = { 	"ns|string|true",

+						"key|string|true"},

+			expectedCode = 200,

+			errorCodes = { 403,404 },  

+			text = { 	

+				"Delete an attribute in the Namespace",

+				"You must be given direct permission for key by AAF"

+				}

+			)

+	@Override

+	public Result<Void> deleteNsAttrib(AuthzTrans trans, String ns, String key) {

+		TimeTaken tt = trans.start("Delete NsAttrib " + ns + ':' + key, Env.SUB);

+		try {

+			// Check inputs

+			final Validator v = new Validator();

+			if(v.nullOrBlank("NS",ns).err() ||

+			   v.nullOrBlank("Key",key).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+

+			// Check if exists already

+			Result<List<Data>> rlnsd = ques.nsDAO.read(trans, ns);

+			if(rlnsd.notOKorIsEmpty()) {

+				return Result.err(rlnsd);

+			}

+			NsDAO.Data nsd = rlnsd.value.get(0);

+

+			// Check for Existence

+			if(nsd.attrib.get(key)==null) {

+				return Result.err(Status.ERR_NotFound, "NS Property [%s:%s] does not exist", ns, key);

+			}

+			

+			// Check if User may del

+			if(!ques.isGranted(trans, trans.user(), Define.ROOT_NS, "attrib", ":com.att.*:"+key, Access.write.name())) {

+				return Result.err(Status.ERR_Denied, "%s may not delete NS Attrib [%s:%s]", trans.user(),ns, key);

+			}

+

+			// Add Attrib

+			nsd.attrib.remove(key);

+			ques.nsDAO.dao().attribRemove(trans,ns,key);

+			return Result.ok();

+		} finally {

+			tt.done();

+		}

+	}

+

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/nss/:id",

+			params = { 	"id|string|true" },

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { 	

+				"Lists the Admin(s), Responsible Party(s), Role(s), Permission(s)",

+				"Credential(s) and Expiration of Credential(s) in Namespace :id",

+			}

+			)

+	@Override

+	public Result<NSS> getNSbyName(AuthzTrans trans, String ns) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("NS", ns).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<List<NsDAO.Data>> rlnd = ques.nsDAO.read(trans, ns);

+		if(rlnd.isOK()) {

+			if(rlnd.isEmpty()) {

+				return Result.err(Status.ERR_NotFound, "No data found for %s",ns);

+			}

+			Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), rlnd.value.get(0), Access.read);

+			if(rnd.notOK()) {

+				return Result.err(rnd); 

+			}

+			

+			

+			Namespace namespace = new Namespace(rnd.value);

+			Result<List<String>> rd = func.getOwners(trans, namespace.name, false);

+			if(rd.isOK()) {

+				namespace.owner = rd.value;

+			}

+			rd = func.getAdmins(trans, namespace.name, false);

+			if(rd.isOK()) {

+				namespace.admin = rd.value;

+			}

+			

+			NSS nss = mapper.newInstance(API.NSS);

+			return mapper.nss(trans, namespace, nss);

+		} else {

+			return Result.err(rlnd);

+		}

+	}

+

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/nss/admin/:id",

+			params = { 	"id|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Lists all Namespaces where Identity :id is an Admin", 

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)" 

+					}

+			)

+	@Override

+	public Result<NSS> getNSbyAdmin(AuthzTrans trans, String user, boolean full) {

+		final Validator v = new Validator();

+		if (v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData, v.errs());

+		}

+		

+		Result<Collection<Namespace>> rn = loadNamepace(trans, user, ".admin", full);

+		if(rn.notOK()) {

+			return Result.err(rn);

+		}

+		if (rn.isEmpty()) {

+			return Result.err(Status.ERR_NotFound, "[%s] is not an admin for any namespaces",user);		

+		}

+		NSS nss = mapper.newInstance(API.NSS);

+		// Note: "loadNamespace" already validates view of Namespace

+		return mapper.nss(trans, rn.value, nss);

+

+	}

+

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/nss/either/:id",

+			params = { 	"id|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Lists all Namespaces where Identity :id is either an Admin or an Owner", 

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)" 

+					}

+			)

+	@Override

+	public Result<NSS> getNSbyEither(AuthzTrans trans, String user, boolean full) {

+		final Validator v = new Validator();

+		if (v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData, v.errs());

+		}

+		

+		Result<Collection<Namespace>> rn = loadNamepace(trans, user, null, full);

+		if(rn.notOK()) {

+			return Result.err(rn);

+		}

+		if (rn.isEmpty()) {

+			return Result.err(Status.ERR_NotFound, "[%s] is not an admin or owner for any namespaces",user);		

+		}

+		NSS nss = mapper.newInstance(API.NSS);

+		// Note: "loadNamespace" already validates view of Namespace

+		return mapper.nss(trans, rn.value, nss);

+	}

+

+	private Result<Collection<Namespace>> loadNamepace(AuthzTrans trans, String user, String endsWith, boolean full) {

+		Result<List<UserRoleDAO.Data>> urd = ques.userRoleDAO.readByUser(trans, user);

+		if(urd.notOKorIsEmpty()) {

+			return Result.err(urd);

+		}

+		Map<String, Namespace> lm = new HashMap<String,Namespace>();

+		Map<String, Namespace> other = full || endsWith==null?null:new TreeMap<String,Namespace>();

+		for(UserRoleDAO.Data urdd : urd.value) {

+			if(full) {

+				if(endsWith==null || urdd.role.endsWith(endsWith)) {

+					RoleDAO.Data rd = RoleDAO.Data.decode(urdd);

+					Result<NsDAO.Data> nsd = ques.mayUser(trans, user, rd, Access.read);

+					if(nsd.isOK()) {

+						Namespace namespace = lm.get(nsd.value.name);

+						if(namespace==null) {

+							namespace = new Namespace(nsd.value);

+							lm.put(namespace.name,namespace);

+						}

+						Result<List<String>> rls = func.getAdmins(trans, namespace.name, false);

+						if(rls.isOK()) {

+							namespace.admin=rls.value;

+						}

+						

+						rls = func.getOwners(trans, namespace.name, false);

+						if(rls.isOK()) {

+							namespace.owner=rls.value;

+						}

+					}

+				}

+			} else { // Shortened version.  Only Namespace Info available from Role.

+				if(Question.ADMIN.equals(urdd.rname) || Question.OWNER.equals(urdd.rname)) {

+					RoleDAO.Data rd = RoleDAO.Data.decode(urdd);

+					Result<NsDAO.Data> nsd = ques.mayUser(trans, user, rd, Access.read);

+					if(nsd.isOK()) {

+						Namespace namespace = lm.get(nsd.value.name);

+						if(namespace==null) {

+							if(other!=null) {

+								namespace = other.remove(nsd.value.name);

+							}

+							if(namespace==null) {

+								namespace = new Namespace(nsd.value);

+								namespace.admin=new ArrayList<String>();

+								namespace.owner=new ArrayList<String>();

+							}

+							if(endsWith==null || urdd.role.endsWith(endsWith)) {

+								lm.put(namespace.name,namespace);

+							} else { 

+								other.put(namespace.name,namespace);

+							}

+						}

+						if(Question.OWNER.equals(urdd.rname)) {

+							namespace.owner.add(urdd.user);

+						} else {

+							namespace.admin.add(urdd.user);

+						}

+					}

+				}

+			}

+		}

+		return Result.ok(lm.values());

+	}

+

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/nss/responsible/:id",

+			params = { 	"id|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Lists all Namespaces where Identity :id is a Responsible Party", 

+						"Note: :id must be fully qualified (i.e. ab1234@csp.att.com)"

+					}

+			)

+	@Override

+	public Result<NSS> getNSbyResponsible(AuthzTrans trans, String user, boolean full) {

+		final Validator v = new Validator();

+		if (v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData, v.errs());

+		}

+		Result<Collection<Namespace>> rn = loadNamepace(trans, user, ".owner",full);

+		if(rn.notOK()) {

+			return Result.err(rn);

+		}

+		if (rn.isEmpty()) {

+			return Result.err(Status.ERR_NotFound, "[%s] is not an owner for any namespaces",user);		

+		}

+		NSS nss = mapper.newInstance(API.NSS);

+		// Note: "loadNamespace" prevalidates

+		return mapper.nss(trans, rn.value, nss);

+	}

+	

+	@ApiDoc(

+			method = GET,  

+			path = "/authz/nss/children/:id",

+			params = { 	"id|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404 }, 

+			text = { 	"Lists all Child Namespaces of Namespace :id", 

+						"Note: This is not a cached read"

+					}

+			)

+	@Override

+	public Result<NSS> getNSsChildren(AuthzTrans trans, String parent) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("NS", parent).err())  {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans, parent);

+		if(rnd.notOK()) {

+			return Result.err(rnd);

+		}

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+

+		Set<Namespace> lm = new HashSet<Namespace>();

+		Result<List<NsDAO.Data>> rlnd = ques.nsDAO.dao().getChildren(trans, parent);

+		if(rlnd.isOK()) {

+			if(rlnd.isEmpty()) {

+				return Result.err(Status.ERR_NotFound, "No data found for %s",parent);

+			}

+			for(NsDAO.Data ndd : rlnd.value) {

+				Namespace namespace = new Namespace(ndd);

+				Result<List<String>> rls = func.getAdmins(trans, namespace.name, false);

+				if(rls.isOK()) {

+					namespace.admin=rls.value;

+				}

+				

+				rls = func.getOwners(trans, namespace.name, false);

+				if(rls.isOK()) {

+					namespace.owner=rls.value;

+				}

+

+				lm.add(namespace);

+			}

+			NSS nss = mapper.newInstance(API.NSS);

+			return mapper.nss(trans,lm, nss);

+		} else {

+			return Result.err(rlnd);

+		}

+	}

+

+

+	@ApiDoc(

+			method = PUT,  

+			path = "/authz/ns",

+			params = {},

+			expectedCode = 200,

+			errorCodes = { 403,404,406 }, 

+			text = { "Replace the Current Description of a Namespace with a new one"

+					}

+			)

+	@Override

+	public Result<Void> updateNsDescription(AuthzTrans trans, REQUEST from) {

+		final Result<Namespace> nsd = mapper.ns(trans, from);

+		final Validator v = new Validator();

+		if(v.ns(nsd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		if(v.nullOrBlank("description", nsd.value.description).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Namespace namespace = nsd.value;

+		Result<List<NsDAO.Data>> rlnd = ques.nsDAO.read(trans, namespace.name);

+		

+		if(rlnd.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_NotFound, "Namespace [%s] does not exist",namespace.name);

+		}

+		

+		if (ques.mayUser(trans, trans.user(), rlnd.value.get(0), Access.write).notOK()) {

+			return Result.err(Status.ERR_Denied, "You do not have approval to change %s",namespace.name);

+		}

+

+		Result<Void> rdr = ques.nsDAO.dao().addDescription(trans, namespace.name, namespace.description);

+		if(rdr.isOK()) {

+			return Result.ok();

+		} else {

+			return Result.err(rdr);

+		}

+	}

+	

+	/**

+	 * deleteNS

+	 * @throws DAOException 

+	 * @see org.onap.aaf.authz.service.AuthzService#deleteNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.String)

+	 */

+	@ApiDoc(

+			method = DELETE,  

+			path = "/authz/ns/:ns",

+			params = { 	"ns|string|true" },

+			expectedCode = 200,

+			errorCodes = { 403,404,424 }, 

+			text = { 	"Delete the Namespace :ns. Namespaces cannot normally be deleted when there ",

+						"are still credentials associated with them, but they can be deleted by setting ",

+						"the \"force\" property. To do this: Add 'force=true' as a query parameter",

+						"<p>WARNING: Using force will delete all credentials attached to this namespace. Use with care.</p>"

+						+ "if the \"force\" property is set to 'force=move', then Permissions and Roles are not deleted,"

+						+ "but are retained, and assigned to the Parent Namespace.  'force=move' is not permitted "

+						+ "at or below Application Scope"

+						}

+			)

+	@Override

+	public Result<Void> deleteNS(AuthzTrans trans, String ns) {

+		return func.deleteNS(trans, ns);

+	}

+

+

+/***********************************

+ * PERM 

+ ***********************************/

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#createOrUpdatePerm(org.onap.aaf.authz.env.AuthzTrans, java.lang.Object, boolean, java.lang.String, java.lang.String, java.lang.String, java.util.List, java.util.List)

+	 */

+	@ApiDoc( 

+			method = POST,  

+			path = "/authz/perm",

+			params = {},

+			expectedCode = 201,

+			errorCodes = {403,404,406,409}, 

+			text = { "Permission consists of:",

+					 "<ul><li>type - a Namespace qualified identifier specifying what kind of resource "

+					 + "is being protected</li>",

+					 "<li>instance - a key, possibly multi-dimensional, that identifies a specific "

+					 + " instance of the type</li>",

+					 "<li>action - what kind of action is allowed</li></ul>",

+					 "Note: instance and action can be an *"

+					 }

+			)

+	@Override

+	public Result<Void> createPerm(final AuthzTrans trans,REQUEST rreq) {		

+		final Result<PermDAO.Data> newPd = mapper.perm(trans, rreq);

+		final Validator v = new Validator(trans);

+		if(v.perm(newPd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans, PermDAO.TABLE, rreq, newPd.value,false,

+			new Mapper.Memo() {

+				@Override

+				public String get() {

+					return "Create Permission [" + 

+						newPd.value.fullType() + '|' + 

+						newPd.value.instance + '|' + 

+						newPd.value.action + ']';

+				}

+			},

+			new MayChange() {

+				private Result<NsDAO.Data> nsd;

+				@Override

+				public Result<?> mayChange() {

+					if(nsd==null) {

+						nsd = ques.mayUser(trans, trans.user(), newPd.value, Access.write);

+					}

+					return nsd;

+				}

+			});

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, newPd.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+		switch(fd.status) {

+			case OK:

+				Result<List<Identity>> rfc = func.createFuture(trans,fd.value, 

+						newPd.value.fullType() + '|' + newPd.value.instance + '|' + newPd.value.action,

+						trans.user(),

+						nsr.value.get(0),

+						"C");

+				if(rfc.isOK()) {

+					return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",

+							newPd.value.ns,

+							newPd.value.type,

+							newPd.value.instance,

+							newPd.value.action);

+				} else {

+				    return Result.err(rfc);

+				}

+			case Status.ACC_Now:

+				return func.createPerm(trans, newPd.value, true);

+			default:

+				return Result.err(fd);

+		}	

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/perms/:type",

+			params = {"type|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List All Permissions that match the :type element of the key" }

+			)

+	@Override

+	public Result<PERMS> getPermsByType(AuthzTrans trans, final String permType) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("PermType", permType).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<List<PermDAO.Data>> rlpd = ques.getPermsByType(trans, permType);

+		if(rlpd.notOK()) {

+			return Result.err(rlpd);

+		}

+

+//		We don't have instance & action for mayUserView... do we want to loop through all returned here as well as in mapper?

+//		Result<NsDAO.Data> r;

+//		if((r = ques.mayUserViewPerm(trans, trans.user(), permType)).notOK())return Result.err(r);

+		

+		PERMS perms = mapper.newInstance(API.PERMS);

+		if(!rlpd.isEmpty()) {

+			// Note: Mapper will restrict what can be viewed

+			return mapper.perms(trans, rlpd.value, perms, true);

+		}

+		return Result.ok(perms);

+	}

+	

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/perms/:type/:instance/:action",

+			params = {"type|string|true",

+					  "instance|string|true",

+					  "action|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List Permissions that match key; :type, :instance and :action" }

+			)

+	@Override

+	public Result<PERMS> getPermsByName(AuthzTrans trans, String type, String instance, String action) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("PermType", type).err()

+				|| v.nullOrBlank("PermInstance", instance).err()

+				|| v.nullOrBlank("PermAction", action).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<List<PermDAO.Data>> rlpd = ques.getPermsByName(trans, type, instance, action);

+		if(rlpd.notOK()) {

+			return Result.err(rlpd);

+		}

+

+		PERMS perms = mapper.newInstance(API.PERMS);

+		if(!rlpd.isEmpty()) {

+			// Note: Mapper will restrict what can be viewed

+			return mapper.perms(trans, rlpd.value, perms, true);

+		}

+		return Result.ok(perms);

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/perms/user/:user",

+			params = {"user|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List All Permissions that match user :user",

+					 "<p>'user' must be expressed as full identity (ex: id@full.domain.com)</p>"}

+			)

+	@Override

+	public Result<PERMS> getPermsByUser(AuthzTrans trans, String user) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<List<PermDAO.Data>> rlpd = ques.getPermsByUser(trans, user, trans.forceRequested());

+		if(rlpd.notOK()) {

+			return Result.err(rlpd);

+		}

+		

+		PERMS perms = mapper.newInstance(API.PERMS);

+		

+		if(rlpd.isEmpty()) {

+			return Result.ok(perms);

+		}

+		// Note: Mapper will restrict what can be viewed

+		//   if user is the same as that which is looked up, no filtering is required

+		return mapper.perms(trans, rlpd.value, 

+				perms, 

+				!user.equals(trans.user()));

+	}

+	

+	@ApiDoc( 

+			method = POST,  

+			path = "/authz/perms/user/:user",

+			params = {"user|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List All Permissions that match user :user",

+					 "<p>'user' must be expressed as full identity (ex: id@full.domain.com)</p>",

+					 "",

+					 "Present Queries as one or more Permissions (see ContentType Links below for format).",

+					 "",

+					 "If the Caller is Granted this specific Permission, and the Permission is valid",

+					 "  for the User, it will be included in response Permissions, along with",

+					 "  all the normal permissions on the 'GET' version of this call.  If it is not",

+					 "  valid, or Caller does not have permission to see, it will be removed from the list",

+					 "",

+					 "  *Note: This design allows you to make one call for all expected permissions",

+					 " The permission to be included MUST be:",

+					 "     <user namespace>.access|:<ns|role|perm>[:key]|<create|read|write>",

+					 "   examples:",

+					 "     com.att.myns.access|:ns|write",

+					 "     com.att.myns.access|:role:myrole|create",

+					 "     com.att.myns.access|:perm:mytype:myinstance:myaction|read",

+					 ""

+					 }

+			)

+	@Override

+	public Result<PERMS> getPermsByUser(AuthzTrans trans, PERMS _perms, String user) {

+	    	PERMS perms = _perms;

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		//////////////

+		Result<List<PermDAO.Data>> rlpd = ques.getPermsByUser(trans, user,trans.forceRequested());

+		if(rlpd.notOK()) {

+			return Result.err(rlpd);

+		}

+		

+		/*//TODO 

+		  1) See if allowed to query

+		  2) See if User is allowed

+		  */

+		Result<List<PermDAO.Data>> in = mapper.perms(trans, perms);

+		if(in.isOKhasData()) {

+			List<PermDAO.Data> out = rlpd.value;

+			boolean ok;

+			for(PermDAO.Data pdd : in.value) {

+				ok = false;

+				if("access".equals(pdd.type)) {

+					Access access = Access.valueOf(pdd.action);

+					String[] mdkey = Split.splitTrim(':',pdd.instance);

+					if(mdkey.length>1) {

+						String type = mdkey[1];

+						if("role".equals(type)) {

+							if(mdkey.length>2) {

+								RoleDAO.Data rdd = new RoleDAO.Data();

+								rdd.ns=pdd.ns;

+								rdd.name=mdkey[2];

+								ok = ques.mayUser(trans, trans.user(), rdd, Access.read).isOK() && ques.mayUser(trans, user, rdd , access).isOK();

+							}

+						} else if("perm".equals(type)) {

+							if(mdkey.length>4) { // also need instance/action

+								PermDAO.Data p = new PermDAO.Data();

+								p.ns=pdd.ns;

+								p.type=mdkey[2];

+								p.instance=mdkey[3];

+								p.action=mdkey[4];

+								ok = ques.mayUser(trans, trans.user(), p, Access.read).isOK() && ques.mayUser(trans, user, p , access).isOK();

+							}

+						} else if("ns".equals(type)) {

+							NsDAO.Data ndd = new NsDAO.Data();

+							ndd.name=pdd.ns;

+							ok = ques.mayUser(trans, trans.user(), ndd, Access.read).isOK() && ques.mayUser(trans, user, ndd , access).isOK();

+						}

+					}

+				}

+				if(ok) {

+					out.add(pdd);

+				}

+			}

+		}		

+		

+		perms = mapper.newInstance(API.PERMS);

+		if(rlpd.isEmpty()) {

+			return Result.ok(perms);

+		}

+		// Note: Mapper will restrict what can be viewed

+		//   if user is the same as that which is looked up, no filtering is required

+		return mapper.perms(trans, rlpd.value, 

+				perms, 

+				!user.equals(trans.user()));

+	}

+	

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/perms/role/:role",

+			params = {"role|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List All Permissions that are granted to :role" }

+			)

+	@Override

+	public Result<PERMS> getPermsByRole(AuthzTrans trans,String role) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Role", role).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques,role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+

+		Result<NsDAO.Data> r = ques.mayUser(trans, trans.user(), rrdd.value, Access.read);

+		if(r.notOK()) {

+			return Result.err(r);

+		}

+

+		PERMS perms = mapper.newInstance(API.PERMS);

+

+		Result<List<PermDAO.Data>> rlpd = ques.getPermsByRole(trans, role, trans.forceRequested());

+		if(rlpd.isOKhasData()) {

+			// Note: Mapper will restrict what can be viewed

+			return mapper.perms(trans, rlpd.value, perms, true);

+		}

+		return Result.ok(perms);

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/perms/ns/:ns",

+			params = {"ns|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "List All Permissions that are in Namespace :ns" }

+			)

+	@Override

+	public Result<PERMS> getPermsByNS(AuthzTrans trans,String ns) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("NS", ns).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans, ns);

+		if(rnd.notOK()) {

+			return Result.err(rnd);

+		}

+

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 	

+		}

+		

+		Result<List<PermDAO.Data>> rlpd = ques.permDAO.readNS(trans, ns);

+		if(rlpd.notOK()) {

+			return Result.err(rlpd);

+		}

+

+		PERMS perms = mapper.newInstance(API.PERMS);

+		if(!rlpd.isEmpty()) {

+			// Note: Mapper will restrict what can be viewed

+			return mapper.perms(trans, rlpd.value,perms, true);

+		}

+		return Result.ok(perms);

+	}

+	

+	@ApiDoc( 

+			method = PUT,  

+			path = 	"/authz/perm/:type/:instance/:action",

+			params = {"type|string|true",

+					  "instance|string|true",

+			  		  "action|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406, 409 }, 

+			text = { "Rename the Permission referenced by :type :instance :action, and "

+					+ "rename (copy/delete) to the Permission described in PermRequest" }

+			)

+	@Override

+	public Result<Void> renamePerm(final AuthzTrans trans,REQUEST rreq, String origType, String origInstance, String origAction) {

+		final Result<PermDAO.Data> newPd = mapper.perm(trans, rreq);

+		final Validator v = new Validator(trans);

+		if(v.perm(newPd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		if (ques.mayUser(trans, trans.user(), newPd.value,Access.write).notOK()) {

+			return Result.err(Status.ERR_Denied, "You do not have approval to change Permission [%s.%s|%s|%s]",

+					newPd.value.ns,newPd.value.type,newPd.value.instance,newPd.value.action);

+		}

+		

+		Result<NsSplit> nss = ques.deriveNsSplit(trans, origType);

+		Result<List<PermDAO.Data>> origRlpd = ques.permDAO.read(trans, nss.value.ns, nss.value.name, origInstance, origAction); 

+		

+		if(origRlpd.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound, 

+					"Permission [%s|%s|%s] does not exist",

+					origType,origInstance,origAction);

+		}

+		

+		PermDAO.Data origPd = origRlpd.value.get(0);

+

+		if (!origPd.ns.equals(newPd.value.ns)) {

+			return Result.err(Status.ERR_Denied, "Cannot change namespace with rename command. " +

+					"<new type> must start with [" + origPd.ns + "]");

+		}

+		

+		if ( origPd.type.equals(newPd.value.type) && 

+				origPd.action.equals(newPd.value.action) && 

+				origPd.instance.equals(newPd.value.instance) ) {

+			return Result.err(Status.ERR_ConflictAlreadyExists, "New Permission must be different than original permission");

+		}

+		

+		Set<String> origRoles = origPd.roles(false);

+		if (!origRoles.isEmpty()) {

+			Set<String> roles = newPd.value.roles(true);

+			for (String role : origPd.roles) {

+				roles.add(role); 

+			}

+		}	

+		

+		newPd.value.description = origPd.description;

+		

+		Result<Void> rv = null;

+		

+		rv = func.createPerm(trans, newPd.value, false);

+		if (rv.isOK()) {

+			rv = func.deletePerm(trans, origPd, true, false);

+		}

+		return rv;

+	}

+	

+	@ApiDoc( 

+			method = PUT,  

+			path = "/authz/perm",

+			params = {},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "Add Description Data to Perm" }

+			)

+	@Override

+	public Result<Void> updatePermDescription(AuthzTrans trans, REQUEST from) {

+		final Result<PermDAO.Data> pd = mapper.perm(trans, from);

+		final Validator v = new Validator(trans);

+		if(v.perm(pd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		if(v.nullOrBlank("description", pd.value.description).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		final PermDAO.Data perm = pd.value;

+		if(ques.permDAO.read(trans, perm.ns, perm.type, perm.instance,perm.action).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_NotFound, "Permission [%s.%s|%s|%s] does not exist",

+				perm.ns,perm.type,perm.instance,perm.action);

+		}

+

+		if (ques.mayUser(trans, trans.user(), perm, Access.write).notOK()) {

+			return Result.err(Status.ERR_Denied, "You do not have approval to change Permission [%s.%s|%s|%s]",

+					perm.ns,perm.type,perm.instance,perm.action);

+		}

+

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, pd.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+

+		Result<Void> rdr = ques.permDAO.addDescription(trans, perm.ns, perm.type, perm.instance,

+				perm.action, perm.description);

+		if(rdr.isOK()) {

+			return Result.ok();

+		} else {

+			return Result.err(rdr);

+		}

+

+	}

+	

+    @ApiDoc(

+            method = PUT,

+            path = "/authz/role/perm",

+            params = {},

+            expectedCode = 201,

+            errorCodes = {403,404,406,409},

+            text = { "Set a permission's roles to roles given" }

+           )

+

+	@Override

+	public Result<Void> resetPermRoles(final AuthzTrans trans, REQUEST rreq) {

+		final Result<PermDAO.Data> updt = mapper.permFromRPRequest(trans, rreq);

+		if(updt.notOKorIsEmpty()) {

+			return Result.err(updt);

+		}

+

+		final Validator v = new Validator(trans);

+		if(v.perm(updt).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<NsDAO.Data> nsd = ques.mayUser(trans, trans.user(), updt.value, Access.write);

+		if (nsd.notOK()) {

+			return Result.err(nsd);

+		}

+

+		// Read full set to get CURRENT values

+		Result<List<PermDAO.Data>> rcurr = ques.permDAO.read(trans, 

+				updt.value.ns, 

+				updt.value.type, 

+				updt.value.instance, 

+				updt.value.action);

+		

+		if(rcurr.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound, 

+					"Permission [%s.%s|%s|%s] does not exist",

+					 updt.value.ns,updt.value.type,updt.value.instance,updt.value.action);

+		}

+		

+		// Create a set of Update Roles, which are in Internal Format

+		Set<String> updtRoles = new HashSet<String>();

+		Result<NsSplit> nss;

+		for(String role : updt.value.roles(false)) {

+			nss = ques.deriveNsSplit(trans, role);

+			if(nss.isOK()) {

+				updtRoles.add(nss.value.ns + '|' + nss.value.name);

+			} else {

+				trans.error().log(nss.errorString());

+			}

+		}

+

+		Result<Void> rv = null;

+		

+		for(PermDAO.Data curr : rcurr.value) {

+			Set<String> currRoles = curr.roles(false);

+			// must add roles to this perm, and add this perm to each role 

+			// in the update, but not in the current			

+			for (String role : updtRoles) {

+				if (!currRoles.contains(role)) {

+					Result<RoleDAO.Data> key = RoleDAO.Data.decode(trans, ques, role);

+					if(key.isOKhasData()) {

+						Result<List<RoleDAO.Data>> rrd = ques.roleDAO.read(trans, key.value);

+						if(rrd.isOKhasData()) {

+							for(RoleDAO.Data r : rrd.value) {

+								rv = func.addPermToRole(trans, r, curr, false);

+								if (rv.notOK() && rv.status!=Result.ERR_ConflictAlreadyExists) {

+									return Result.err(rv);

+								}

+							}

+						} else {

+							return Result.err(rrd);

+						}

+					}

+				}

+			}

+			// similarly, must delete roles from this perm, and delete this perm from each role

+			// in the update, but not in the current

+			for (String role : currRoles) {

+				if (!updtRoles.contains(role)) {

+					Result<RoleDAO.Data> key = RoleDAO.Data.decode(trans, ques, role);

+					if(key.isOKhasData()) {

+						Result<List<RoleDAO.Data>> rdd = ques.roleDAO.read(trans, key.value);

+						if(rdd.isOKhasData()) {

+							for(RoleDAO.Data r : rdd.value) {

+								rv = func.delPermFromRole(trans, r, curr, true);

+								if (rv.notOK() && rv.status!=Status.ERR_PermissionNotFound) {

+									return Result.err(rv);

+								}

+							}

+						}

+					}

+				}

+			}				

+		} 

+		return rv==null?Result.ok():rv;		

+	}

+	

+	@ApiDoc( 

+			method = DELETE,

+			path = "/authz/perm",

+			params = {},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "Delete the Permission referenced by PermKey.",

+					"You cannot normally delete a permission which is still granted to roles,",

+					"however the \"force\" property allows you to do just that. To do this: Add",

+					"'force=true' as a query parameter.",

+					"<p>WARNING: Using force will ungrant this permission from all roles. Use with care.</p>" }

+			)

+	@Override

+	public Result<Void> deletePerm(final AuthzTrans trans, REQUEST from) {

+		Result<PermDAO.Data> pd = mapper.perm(trans, from);

+		if(pd.notOK()) {

+			return Result.err(pd);

+		}

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank(pd.value).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		final PermDAO.Data perm = pd.value;

+		if (ques.permDAO.read(trans, perm).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound, "Permission [%s.%s|%s|%s] does not exist",

+					perm.ns,perm.type,perm.instance,perm.action	);

+		}

+

+		Result<FutureDAO.Data> fd = mapper.future(trans,PermDAO.TABLE,from,perm,false,

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Delete Permission [" + perm.fullPerm() + ']';

+					}

+				},

+			new MayChange() {

+				private Result<NsDAO.Data> nsd;

+				@Override

+				public Result<?> mayChange() {

+					if(nsd==null) {

+						nsd = ques.mayUser(trans, trans.user(), perm, Access.write);

+					}

+					return nsd;

+				}

+			});

+		

+		switch(fd.status) {

+		case OK:

+			Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, perm.ns);

+			if(nsr.notOKorIsEmpty()) {

+				return Result.err(nsr);

+			}

+			

+			Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+					perm.encode(), trans.user(),nsr.value.get(0),"D");

+			if(rfc.isOK()) {

+				return Result.err(Status.ACC_Future, "Perm Deletion [%s] is saved for future processing",perm.encode());

+			} else { 

+				return Result.err(rfc);

+			}

+		case Status.ACC_Now:

+			return func.deletePerm(trans,perm,trans.forceRequested(), false);

+		default:

+			return Result.err(fd);

+		}			

+	}	

+	

+	@ApiDoc( 

+			method = DELETE,

+			path = "/authz/perm/:name/:type/:action",

+			params = {"type|string|true",

+					  "instance|string|true",

+	  		  		  "action|string|true"},

+			expectedCode = 200,

+			errorCodes = { 404,406 }, 

+			text = { "Delete the Permission referenced by :type :instance :action",

+					"You cannot normally delete a permission which is still granted to roles,",

+					"however the \"force\" property allows you to do just that. To do this: Add",

+					"'force=true' as a query parameter",

+					"<p>WARNING: Using force will ungrant this permission from all roles. Use with care.</p>"}

+			)

+	@Override

+	public Result<Void> deletePerm(AuthzTrans trans, String type, String instance, String action) {

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("Type",type)

+			.nullOrBlank("Instance",instance)

+			.nullOrBlank("Action",action)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<PermDAO.Data> pd = ques.permFrom(trans, type, instance, action);

+		if(pd.isOK()) {

+			return func.deletePerm(trans, pd.value, trans.forceRequested(), false);

+		} else {

+		    return Result.err(pd);

+		}

+	}

+

+/***********************************

+ * ROLE 

+ ***********************************/

+    @ApiDoc(

+            method = POST,

+            path = "/authz/role",

+            params = {},

+            expectedCode = 201,

+            errorCodes = {403,404,406,409},

+            text = {

+

+                "Roles are part of Namespaces",

+                "Examples:",

+                "<ul><li> org.osaaf - A Possible root Namespace for maintaining AAF</li>",

+                "Roles do not include implied permissions for an App.  Instead, they contain explicit Granted Permissions by any Namespace in AAF (See Permissions)",

+                "Restrictions on Role Names:",

+                "<ul><li>Must start with valid Namespace name, terminated by . (dot/period)</li>",

+                "<li>Allowed Characters are a-zA-Z0-9._-</li>",

+                "<li>role names are Case Sensitive</li></ul>",

+                "The right questions to ask for defining and populating a Role in AAF, therefore, are:",

+                "<ul><li>'What Job Function does this represent?'</li>",

+                "<li>'Does this person perform this Job Function?'</li></ul>" }

+           )

+

+	@Override

+	public Result<Void> createRole(final AuthzTrans trans, REQUEST from) {

+		final Result<RoleDAO.Data> rd = mapper.role(trans, from);

+		final Validator v = new Validator(trans);

+		if(v.role(rd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		final RoleDAO.Data role = rd.value;

+		if(ques.roleDAO.read(trans, role.ns, role.name).isOKhasData()) {

+			return Result.err(Status.ERR_ConflictAlreadyExists, "Role [" + role.fullName() + "] already exists");

+		}

+

+		Result<FutureDAO.Data> fd = mapper.future(trans,RoleDAO.TABLE,from,role,false,

+			new Mapper.Memo() {

+				@Override

+				public String get() {

+					return "Create Role [" + 

+						rd.value.fullName() + 

+						']';

+				}

+			},

+			new MayChange() {

+				private Result<NsDAO.Data> nsd;

+				@Override

+				public Result<?> mayChange() {

+					if(nsd==null) {

+						nsd = ques.mayUser(trans, trans.user(), role, Access.write);

+					}

+					return nsd;

+				}

+			});

+		

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+

+		switch(fd.status) {

+			case OK:

+				Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+						role.encode(), trans.user(),nsr.value.get(0),"C");

+				if(rfc.isOK()) {

+					return Result.err(Status.ACC_Future, "Role [%s.%s] is saved for future processing",

+							rd.value.ns,

+							rd.value.name);

+				} else { 

+					return Result.err(rfc);

+				}

+			case Status.ACC_Now:

+				Result<RoleDAO.Data> rdr = ques.roleDAO.create(trans, role);

+				if(rdr.isOK()) {

+					return Result.ok();

+				} else {

+					return Result.err(rdr);

+				}

+			default:

+				return Result.err(fd);

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#getRolesByName(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+    @ApiDoc(

+            method = GET,

+            path = "/authz/roles/:role",

+            params = {"role|string|true"}, 

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "List Roles that match :role",

+            		 "Note: You must have permission to see any given role"

+            	   }

+           )

+	@Override

+	public Result<ROLES> getRolesByName(AuthzTrans trans, String role) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Role", role).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		// Determine if User can ask this question

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);

+		if(rrdd.isOKhasData()) {

+			Result<NsDAO.Data> r;

+			if((r = ques.mayUser(trans, trans.user(), rrdd.value, Access.read)).notOK()) {

+				return Result.err(r);

+			}

+		} else {

+			return Result.err(rrdd);

+		}

+		

+		// Look up data

+		Result<List<RoleDAO.Data>> rlrd = ques.getRolesByName(trans, role);

+		if(rlrd.isOK()) {

+			// Note: Mapper will restrict what can be viewed

+			ROLES roles = mapper.newInstance(API.ROLES);

+			return mapper.roles(trans, rlrd.value, roles, true);

+		} else {

+			return Result.err(rlrd);

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#getRolesByUser(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+    @ApiDoc(

+            method = GET,

+            path = "/authz/roles/user/:name",

+            params = {"name|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "List all Roles that match user :name",

+					 "'user' must be expressed as full identity (ex: id@full.domain.com)",

+           		 	"Note: You must have permission to see any given role"

+            }

+           )

+

+	@Override

+	public Result<ROLES> getRolesByUser(AuthzTrans trans, String user) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		ROLES roles = mapper.newInstance(API.ROLES);

+		// Get list of roles per user, then add to Roles as we go

+		Result<List<RoleDAO.Data>> rlrd;

+		Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, user);

+		if(rlurd.isOKhasData()) {

+			for(UserRoleDAO.Data urd : rlurd.value ) {

+				rlrd = ques.roleDAO.read(trans, urd.ns,urd.rname);

+				// Note: Mapper will restrict what can be viewed

+				//   if user is the same as that which is looked up, no filtering is required

+				if(rlrd.isOKhasData()) {

+					mapper.roles(trans, rlrd.value,roles, !user.equals(trans.user()));

+				}

+			}

+		}

+		return Result.ok(roles);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#getRolesByNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+    @ApiDoc(

+            method = GET,

+            path = "/authz/roles/ns/:ns",

+            params = {"ns|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "List all Roles for the Namespace :ns", 

+           		 	 "Note: You must have permission to see any given role"

+            }

+           )

+

+	@Override

+	public Result<ROLES> getRolesByNS(AuthzTrans trans, String ns) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("NS", ns).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		// check if user is allowed to view NS

+		Result<NsDAO.Data> rnsd = ques.deriveNs(trans, ns); 

+		if(rnsd.notOK()) {

+			return Result.err(rnsd); 	

+		}

+		rnsd = ques.mayUser(trans, trans.user(), rnsd.value, Access.read);

+		if(rnsd.notOK()) {

+			return Result.err(rnsd); 	

+		}

+

+		TimeTaken tt = trans.start("MAP Roles by NS to Roles", Env.SUB);

+		try {

+			ROLES roles = mapper.newInstance(API.ROLES);

+			// Get list of roles per user, then add to Roles as we go

+			Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.readNS(trans, ns);

+			if(rlrd.isOK()) {

+				if(!rlrd.isEmpty()) {

+					// Note: Mapper doesn't need to restrict what can be viewed, because we did it already.

+					mapper.roles(trans,rlrd.value,roles,false);

+				}

+				return Result.ok(roles);

+			} else {

+				return Result.err(rlrd);

+			}

+		} finally {

+			tt.done();

+		}

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#getRolesByNS(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+    @ApiDoc(

+            method = GET,

+            path = "/authz/roles/name/:name",

+            params = {"name|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "List all Roles for only the Name of Role (without Namespace)", 

+           		 	 "Note: You must have permission to see any given role"

+            }

+           )

+	@Override

+	public Result<ROLES> getRolesByNameOnly(AuthzTrans trans, String name) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Name", name).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		// User Mapper to make sure user is allowed to view NS

+

+		TimeTaken tt = trans.start("MAP Roles by Name to Roles", Env.SUB);

+		try {

+			ROLES roles = mapper.newInstance(API.ROLES);

+			// Get list of roles per user, then add to Roles as we go

+			Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.readName(trans, name);

+			if(rlrd.isOK()) {

+				if(!rlrd.isEmpty()) {

+					// Note: Mapper will restrict what can be viewed

+					mapper.roles(trans,rlrd.value,roles,true);

+				}

+				return Result.ok(roles);

+			} else {

+				return Result.err(rlrd);

+			}

+		} finally {

+			tt.done();

+		}

+	}

+

+    @ApiDoc(

+            method = GET,

+            path = "/authz/roles/perm/:type/:instance/:action",

+            params = {"type|string|true",

+                      "instance|string|true",

+                      "action|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "Find all Roles containing the given Permission." +

+                     "Permission consists of:",

+                     "<ul><li>type - a Namespace qualified identifier specifying what kind of resource "

+                     + "is being protected</li>",

+                     "<li>instance - a key, possibly multi-dimensional, that identifies a specific "

+                     + " instance of the type</li>",

+                     "<li>action - what kind of action is allowed</li></ul>",

+                     "Notes: instance and action can be an *",

+            		 "       You must have permission to see any given role"

+                     }

+           )

+

+	@Override

+	public Result<ROLES> getRolesByPerm(AuthzTrans trans, String type, String instance, String action) {

+		final Validator v = new Validator(trans);

+		if(v.permType(type,null)

+			.permInstance(instance)

+			.permAction(action)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		TimeTaken tt = trans.start("Map Perm Roles Roles", Env.SUB);

+		try {

+			ROLES roles = mapper.newInstance(API.ROLES);

+			// Get list of roles per user, then add to Roles as we go

+			Result<NsSplit> nsSplit = ques.deriveNsSplit(trans, type);

+			if(nsSplit.isOK()) {

+				PermDAO.Data pdd = new PermDAO.Data(nsSplit.value, instance, action);

+				Result<?> res;

+				if((res=ques.mayUser(trans, trans.user(), pdd, Question.Access.read)).notOK()) {

+					return Result.err(res);

+				}

+				

+				Result<List<PermDAO.Data>> pdlr = ques.permDAO.read(trans, pdd);

+				if(pdlr.isOK())for(PermDAO.Data pd : pdlr.value) {

+					Result<List<RoleDAO.Data>> rlrd;

+					for(String r : pd.roles) {

+						Result<String[]> rs = RoleDAO.Data.decodeToArray(trans, ques, r);

+						if(rs.isOK()) {

+							rlrd = ques.roleDAO.read(trans, rs.value[0],rs.value[1]);

+							// Note: Mapper will restrict what can be viewed

+							if(rlrd.isOKhasData()) {

+								mapper.roles(trans,rlrd.value,roles,true);

+							}

+						}

+					}

+				}

+			}

+			return Result.ok(roles);

+		} finally {

+			tt.done();

+		}

+	}

+

+    @ApiDoc(

+            method = PUT,

+            path = "/authz/role",

+            params = {},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "Add Description Data to a Role" }

+           )

+

+	@Override

+	public Result<Void> updateRoleDescription(AuthzTrans trans, REQUEST from) {

+		final Result<RoleDAO.Data> rd = mapper.role(trans, from);

+		final Validator v = new Validator(trans);

+		if(v.role(rd).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		} {

+		if(v.nullOrBlank("description", rd.value.description).err()) {

+		    return Result.err(Status.ERR_BadData,v.errs());

+		}

+		}

+		final RoleDAO.Data role = rd.value;

+		if(ques.roleDAO.read(trans, role.ns, role.name).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_NotFound, "Role [" + role.fullName() + "] does not exist");

+		}

+

+		if (ques.mayUser(trans, trans.user(), role, Access.write).notOK()) {

+			return Result.err(Status.ERR_Denied, "You do not have approval to change " + role.fullName());

+		}

+

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+

+		Result<Void> rdr = ques.roleDAO.addDescription(trans, role.ns, role.name, role.description);

+		if(rdr.isOK()) {

+			return Result.ok();

+		} else {

+			return Result.err(rdr);

+		}

+

+	}

+	

+    @ApiDoc(

+            method = POST,

+            path = "/authz/role/perm",

+            params = {},

+            expectedCode = 201,

+            errorCodes = {403,404,406,409},

+            text = { "Grant a Permission to a Role",

+                     "Permission consists of:", 

+                     "<ul><li>type - a Namespace qualified identifier specifying what kind of resource "

+                     + "is being protected</li>",

+                     "<li>instance - a key, possibly multi-dimensional, that identifies a specific "

+                     + " instance of the type</li>",

+                     "<li>action - what kind of action is allowed</li></ul>",

+                     "Note: instance and action can be an *",

+                     "Note: Using the \"force\" property will create the Permission, if it doesn't exist AND the requesting " +

+                     " ID is allowed to create.  It will then grant",

+                     "  the permission to the role in one step. To do this: add 'force=true' as a query parameter."

+					}

+           )

+

+	@Override

+	public Result<Void> addPermToRole(final AuthzTrans trans, REQUEST rreq) {

+		// Translate Request into Perm and Role Objects

+		final Result<PermDAO.Data> rpd = mapper.permFromRPRequest(trans, rreq);

+		if(rpd.notOKorIsEmpty()) {

+			return Result.err(rpd);

+		}

+		final Result<RoleDAO.Data> rrd = mapper.roleFromRPRequest(trans, rreq);

+		if(rrd.notOKorIsEmpty()) {

+			return Result.err(rrd);

+		}

+		

+		// Validate Role and Perm values

+		final Validator v = new Validator(trans);

+		if(v.perm(rpd.value)

+			.role(rrd.value)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<List<RoleDAO.Data>> rlrd = ques.roleDAO.read(trans, rrd.value.ns, rrd.value.name);

+		if(rlrd.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_RoleNotFound, "Role [%s] does not exist", rrd.value.fullName());

+		}

+		

+		// Check Status of Data in DB (does it exist)

+		Result<List<PermDAO.Data>> rlpd = ques.permDAO.read(trans, rpd.value.ns, 

+				rpd.value.type, rpd.value.instance, rpd.value.action);

+		PermDAO.Data createPerm = null; // if not null, create first

+		if(rlpd.notOKorIsEmpty()) { // Permission doesn't exist

+			if(trans.forceRequested()) {

+				// Remove roles from perm data object so we just create the perm here

+				createPerm = rpd.value;

+				createPerm.roles.clear();

+			} else {

+				return Result.err(Status.ERR_PermissionNotFound,"Permission [%s.%s|%s|%s] does not exist", 

+						rpd.value.ns,rpd.value.type,rpd.value.instance,rpd.value.action);

+			}

+		} else {

+			if (rlpd.value.get(0).roles(false).contains(rrd.value.encode())) {

+				return Result.err(Status.ERR_ConflictAlreadyExists,

+						"Permission [%s.%s|%s|%s] already granted to Role [%s.%s]",

+						rpd.value.ns,rpd.value.type,rpd.value.instance,rpd.value.action,

+						rrd.value.ns,rrd.value.name

+					);

+			}

+		}

+

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans, PermDAO.TABLE, rreq, rpd.value,true, // Allow grants to create Approvals

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Grant Permission [" + rpd.value.fullPerm() + ']' +

+							" to Role [" + rrd.value.fullName() + "]";

+					}

+				},

+				new MayChange() {

+					private Result<NsDAO.Data> nsd;

+					@Override

+					public Result<?> mayChange() {

+						if(nsd==null) {

+							nsd = ques.mayUser(trans, trans.user(), rpd.value, Access.write);

+						}

+						return nsd;

+					}

+				});

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rpd.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+		switch(fd.status) {

+		case OK:

+			Result<List<Identity>> rfc = func.createFuture(trans,fd.value, 

+					rpd.value.fullPerm(),

+					trans.user(),

+					nsr.value.get(0),

+					"G");

+			if(rfc.isOK()) {

+				return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",

+						rpd.value.ns,

+						rpd.value.type,

+						rpd.value.instance,

+						rpd.value.action);

+			} else { 

+				return Result.err(rfc);

+			}

+		case Status.ACC_Now:

+			Result<Void> rv = null;

+			if(createPerm!=null) {// has been validated for creating

+				rv = func.createPerm(trans, createPerm, false);

+			}

+			if(rv==null || rv.isOK()) {

+				rv = func.addPermToRole(trans, rrd.value, rpd.value, false);

+			}

+			return rv;

+		default:

+			return Result.err(fd);

+		}

+		

+	}

+

+	/**

+	 * Create a RoleDAO.Data

+	 * @param trans

+	 * @param roleFullName

+	 * @return

+	 */

+    @ApiDoc(

+            method = DELETE,

+            path = "/authz/role/:role/perm",

+            params = {"role|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "Ungrant a permission from Role :role" }

+           )

+

+	@Override

+	public Result<Void> delPermFromRole(final AuthzTrans trans, REQUEST rreq) {

+		final Result<PermDAO.Data> updt = mapper.permFromRPRequest(trans, rreq);

+		if(updt.notOKorIsEmpty()) {

+			return Result.err(updt);

+		}

+		final Result<RoleDAO.Data> rrd = mapper.roleFromRPRequest(trans, rreq);

+		if(rrd.notOKorIsEmpty()) {

+			return Result.err(rrd);

+		}

+		

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank(updt.value)

+			.nullOrBlank(rrd.value)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<List<PermDAO.Data>> rlpd = ques.permDAO.read(trans, updt.value.ns, updt.value.type, 

+				updt.value.instance, updt.value.action);

+		

+		if(rlpd.notOKorIsEmpty()) {

+			return Result.err(Status.ERR_PermissionNotFound, 

+				"Permission [%s.%s|%s|%s] does not exist",

+					updt.value.ns,updt.value.type,updt.value.instance,updt.value.action);

+		}

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans, PermDAO.TABLE, rreq, updt.value,true, // allow ungrants requests

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Ungrant Permission [" + updt.value.fullPerm() + ']' +

+							" from Role [" + rrd.value.fullName() + "]";

+					}

+				},

+				new MayChange() {

+					private Result<NsDAO.Data> nsd;

+					@Override

+					public Result<?> mayChange() {

+						if(nsd==null) {

+							nsd = ques.mayUser(trans, trans.user(), updt.value, Access.write);

+						}

+						return nsd;

+					}

+				});

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, updt.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+		switch(fd.status) {

+		case OK:

+			Result<List<Identity>> rfc = func.createFuture(trans,fd.value, 

+					updt.value.fullPerm(),

+					trans.user(),

+					nsr.value.get(0),

+					"UG"

+					);

+			if(rfc.isOK()) {

+				return Result.err(Status.ACC_Future, "Perm [%s.%s|%s|%s] is saved for future processing",

+						updt.value.ns,

+						updt.value.type,

+						updt.value.instance,

+						updt.value.action);

+			} else {

+			    return Result.err(rfc);

+			}

+		case Status.ACC_Now:

+			return func.delPermFromRole(trans, rrd.value, updt.value, false);

+		default:

+			return Result.err(fd);

+		}

+	}

+	

+    @ApiDoc(

+            method = DELETE,

+            path = "/authz/role/:role",

+            params = {"role|string|true"},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "Delete the Role named :role"}

+           )

+

+	@Override

+	public Result<Void> deleteRole(AuthzTrans trans, String role)  {

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,ques,role);

+		if(rrdd.isOKhasData()) {

+			final Validator v = new Validator(trans);

+			if(v.nullOrBlank(rrdd.value).err()) { 

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+			return func.deleteRole(trans, rrdd.value, false, false);

+		} else {

+			return Result.err(rrdd);

+		}

+	}

+

+    @ApiDoc(

+            method = DELETE,

+            path = "/authz/role",

+            params = {},

+            expectedCode = 200,

+            errorCodes = { 404,406 },

+            text = { "Delete the Role referenced by RoleKey",

+					"You cannot normally delete a role which still has permissions granted or users assigned to it,",

+					"however the \"force\" property allows you to do just that. To do this: Add 'force=true'",

+					"as a query parameter.",

+					"<p>WARNING: Using force will remove all users and permission from this role. Use with care.</p>"}

+           )

+

+	@Override

+	public Result<Void> deleteRole(final AuthzTrans trans, REQUEST from) {

+		final Result<RoleDAO.Data> rd = mapper.role(trans, from);

+		final Validator v = new Validator(trans);

+		if(rd==null) {

+			return Result.err(Status.ERR_BadData,"Request does not contain Role");

+		}

+		if(v.nullOrBlank(rd.value).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		final RoleDAO.Data role = rd.value;

+		if(ques.roleDAO.read(trans, role).notOKorIsEmpty() && !trans.forceRequested()) {

+			return Result.err(Status.ERR_RoleNotFound, "Role [" + role.fullName() + "] does not exist");

+		}

+

+		Result<FutureDAO.Data> fd = mapper.future(trans,RoleDAO.TABLE,from,role,false,

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Delete Role [" + role.fullName() + ']' 

+								+ " and all attached user roles";

+					}

+				},

+			new MayChange() {

+				private Result<NsDAO.Data> nsd;

+				@Override

+				public Result<?> mayChange() {

+					if(nsd==null) {

+						nsd = ques.mayUser(trans, trans.user(), role, Access.write);

+					}

+					return nsd;

+				}

+			});

+		

+		switch(fd.status) {

+		case OK:

+			Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rd.value.ns);

+			if(nsr.notOKorIsEmpty()) {

+				return Result.err(nsr);

+			}

+			

+			Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+					role.encode(), trans.user(),nsr.value.get(0),"D");

+			if(rfc.isOK()) {

+				return Result.err(Status.ACC_Future, "Role Deletion [%s.%s] is saved for future processing",

+						rd.value.ns,

+						rd.value.name);

+			} else { 

+				return Result.err(rfc);

+			}

+		case Status.ACC_Now:

+			return func.deleteRole(trans,role,trans.forceRequested(), true /*preapproved*/);

+		default:

+			return Result.err(fd);

+	}

+

+	}

+

+/***********************************

+ * CRED 

+ ***********************************/

+	private class MayCreateCred implements MayChange {

+		private Result<NsDAO.Data> nsd;

+		private AuthzTrans trans;

+		private CredDAO.Data cred;

+		private Executor exec;

+		

+		public MayCreateCred(AuthzTrans trans, CredDAO.Data cred, Executor exec) {

+			this.trans = trans;

+			this.cred = cred;

+			this.exec = exec;

+		}

+

+		@Override

+		public Result<?> mayChange() {

+			if(nsd==null) {

+				nsd = ques.validNSOfDomain(trans, cred.id);

+			}

+			// is Ns of CredID valid?

+			if(nsd.isOK()) {

+				try {

+					// Check Org Policy

+					if(trans.org().validate(trans,Policy.CREATE_MECHID, exec, cred.id)==null) {

+						return Result.ok(); 

+					} else {

+					   Result<?> rmc = ques.mayUser(trans, trans.user(), nsd.value, Access.write);

+					   if(rmc.isOKhasData()) {

+						   return rmc;

+					   }

+					}

+				} catch (Exception e) {

+					trans.warn().log(e);

+				}

+			} else {

+				trans.warn().log(nsd.errorString());

+			}

+			return Result.err(Status.ERR_Denied,"%s is not allowed to create %s in %s",trans.user(),cred.id,cred.ns);

+		}

+	}

+

+	private class MayChangeCred implements MayChange {

+		

+		private Result<NsDAO.Data> nsd;

+		private AuthzTrans trans;

+		private CredDAO.Data cred;

+		public MayChangeCred(AuthzTrans trans, CredDAO.Data cred) {

+			this.trans = trans;

+			this.cred = cred;

+		}

+

+		@Override

+		public Result<?> mayChange() {

+			// User can change himself (but not create)

+			if(trans.user().equals(cred.id)) {

+				return Result.ok();

+			}

+			if(nsd==null) {

+				nsd = ques.validNSOfDomain(trans, cred.id);

+			}

+			// Get the Namespace

+			if(nsd.isOK()) {

+				if(ques.mayUser(trans, trans.user(), nsd.value,Access.write).isOK()) {

+					return Result.ok();

+				}

+				String user[] = Split.split('.',trans.user());

+				if(user.length>2) {

+					String company = user[user.length-1] + '.' + user[user.length-2];

+					if(ques.isGranted(trans, trans.user(), Define.ROOT_NS,"password",company,"reset")) {

+						return Result.ok();

+					}

+				}

+			}

+			return Result.err(Status.ERR_Denied,"%s is not allowed to change %s in %s",trans.user(),cred.id,cred.ns);

+		}

+

+	}

+

+	private final long DAY_IN_MILLIS = 24*3600*1000;

+	

+	@ApiDoc( 

+			method = POST,  

+			path = "/authn/cred",

+			params = {},

+			expectedCode = 201,

+			errorCodes = {403,404,406,409}, 

+			text = { "A credential consists of:",

+					 "<ul><li>id - the ID to create within AAF. The domain is in reverse",

+					 "order of Namespace (i.e. Users of Namespace com.att.myapp would be",

+					 "AB1234@myapp.att.com</li>",

+					 "<li>password - Company Policy Compliant Password</li></ul>",

+					 "Note: AAF does support multiple credentials with the same ID.",

+					 "Check with your organization if you have this implemented."

+					 }

+			)

+	@Override

+	public Result<Void> createUserCred(final AuthzTrans trans, REQUEST from) {

+		final String cmdDescription = ("Create User Credential");

+		TimeTaken tt = trans.start(cmdDescription, Env.SUB);

+		

+		try {

+			Result<CredDAO.Data> rcred = mapper.cred(trans, from, true);

+			if(rcred.isOKhasData()) {

+				rcred = ques.userCredSetup(trans, rcred.value);

+				

+				final Validator v = new Validator();

+				

+				if(v.cred(trans.org(),rcred,true).err()) { // Note: Creates have stricter Validations 

+					return Result.err(Status.ERR_BadData,v.errs());

+				}

+				

+

+				// 2016-4 JG, New Behavior - If MechID is not registered with Org, deny creation

+				Identity mechID =  null;

+				Organization org = trans.org();

+				try {

+					mechID = org.getIdentity(trans, rcred.value.id);

+				} catch (Exception e1) {

+					trans.error().log(e1,rcred.value.id,"cannot be validated at this time");

+				}

+				if(mechID==null || !mechID.isFound()) { 

+					return Result.err(Status.ERR_Policy,"MechIDs must be registered with %s before provisioning in AAF",org.getName());

+				}

+

+				Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rcred.value.ns);

+				if(nsr.notOKorIsEmpty()) {

+					return Result.err(Status.ERR_NsNotFound,"Cannot provision %s on non-existent Namespace %s",mechID.id(),rcred.value.ns);

+				}

+

+				boolean firstID = false;

+				MayChange mc;

+				

+				CassExecutor exec = new CassExecutor(trans, func);

+				Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, rcred.value.id);

+				if (rlcd.isOKhasData()) {

+					if (!org.canHaveMultipleCreds(rcred.value.id)) {

+						return Result.err(Status.ERR_ConflictAlreadyExists, "Credential exists");

+					}

+					for (CredDAO.Data curr : rlcd.value) {

+						if (Chrono.dateOnlyStamp(curr.expires).equals(Chrono.dateOnlyStamp(rcred.value.expires)) && curr.type==rcred.value.type) {

+							return Result.err(Status.ERR_ConflictAlreadyExists, "Credential with same Expiration Date exists, use 'reset'");

+						}

+					}	

+				} else {

+					try {

+					// 2016-04-12 JG If Caller is the Sponsor and is also an Owner of NS, allow without special Perm

+						String theMechID = rcred.value.id;

+						Boolean otherMechIDs = false;

+						// find out if this is the only mechID.  other MechIDs mean special handling (not automated)

+						for(CredDAO.Data cd : ques.credDAO.readNS(trans,nsr.value.get(0).name).value) {

+							if(!cd.id.equals(theMechID)) {

+								otherMechIDs = true;

+								break;

+							}

+						}

+						String reason;

+						// We can say "ID does not exist" here

+						if((reason=org.validate(trans, Policy.CREATE_MECHID, exec, theMechID,trans.user(),otherMechIDs.toString()))!=null) {

+							return Result.err(Status.ERR_Denied, reason); 

+						}

+						firstID=true;

+					} catch (Exception e) {

+						return Result.err(e);

+					}

+				}

+	

+				mc = new MayCreateCred(trans, rcred.value, exec);

+				

+				final CredDAO.Data cdd = rcred.value;

+				Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from, rcred.value,false, // may want to enable in future.

+					new Mapper.Memo() {

+						@Override

+						public String get() {

+							return cmdDescription + " [" + 

+								cdd.id + '|' 

+								+ cdd.type + '|' 

+								+ cdd.expires + ']';

+						}

+					},

+					mc);

+				

+				switch(fd.status) {

+					case OK:

+						Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+								rcred.value.id + '|' + rcred.value.type.toString() + '|' + rcred.value.expires,

+								trans.user(), nsr.value.get(0), "C");

+						if(rfc.isOK()) {

+							return Result.err(Status.ACC_Future, "Credential Request [%s|%s|%s] is saved for future processing",

+									rcred.value.id,

+									Integer.toString(rcred.value.type),

+									rcred.value.expires.toString());

+						} else { 

+							return Result.err(rfc);

+						}

+					case Status.ACC_Now:

+						try {

+							if(firstID) {

+	//							&& !nsr.value.get(0).isAdmin(trans.getUserPrincipal().getName())) {

+								Result<List<String>> admins = func.getAdmins(trans, nsr.value.get(0).name, false);

+								// OK, it's a first ID, and not by NS Admin, so let's set TempPassword length

+								// Note, we only do this on First time, because of possibility of 

+								// prematurely expiring a production id

+								if(admins.isOKhasData() && !admins.value.contains(trans.user())) {

+									rcred.value.expires = org.expiration(null, Expiration.TempPassword).getTime();

+								}

+							}

+						} catch (Exception e) {

+							trans.error().log(e, "While setting expiration to TempPassword");

+						}

+						Result<?>udr = ques.credDAO.create(trans, rcred.value);

+						if(udr.isOK()) {

+							return Result.ok();

+						}

+						return Result.err(udr);

+					default:

+						return Result.err(fd);

+				}

+

+			} else {

+				return Result.err(rcred);

+			}

+		} finally {

+			tt.done();

+		}

+	}

+

+	@ApiDoc(   

+			method = GET,  

+			path = "/authn/creds/ns/:ns",

+			params = {"ns|string|true"},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Return all IDs in Namespace :ns"

+					 }

+			)

+	@Override

+	public Result<USERS> getCredsByNS(AuthzTrans trans, String ns) {

+		final Validator v = new Validator();

+		if(v.ns(ns).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		// check if user is allowed to view NS

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans,ns);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+	

+		TimeTaken tt = trans.start("MAP Creds by NS to Creds", Env.SUB);

+		try {			

+			USERS users = mapper.newInstance(API.USERS);

+			Result<List<CredDAO.Data>> rlcd = ques.credDAO.readNS(trans, ns);

+					

+			if(rlcd.isOK()) {

+				if(!rlcd.isEmpty()) {

+					return mapper.cred(rlcd.value, users);

+				}

+				return Result.ok(users);		

+			} else {

+				return Result.err(rlcd);

+			}

+		} finally {

+			tt.done();

+		}

+			

+	}

+

+	@ApiDoc(   

+			method = GET,  

+			path = "/authn/creds/id/:ns",

+			params = {"id|string|true"},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Return all IDs in for ID"

+					,"(because IDs are multiple, due to multiple Expiration Dates)"

+					 }

+			)

+	@Override

+	public Result<USERS> getCredsByID(AuthzTrans trans, String id) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("ID",id).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		String ns = Question.domain2ns(id);

+		// check if user is allowed to view NS

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans,ns);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+	

+		TimeTaken tt = trans.start("MAP Creds by ID to Creds", Env.SUB);

+		try {			

+			USERS users = mapper.newInstance(API.USERS);

+			Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, id);

+					

+			if(rlcd.isOK()) {

+				if(!rlcd.isEmpty()) {

+					return mapper.cred(rlcd.value, users);

+				}

+				return Result.ok(users);		

+			} else {

+				return Result.err(rlcd);

+			}

+		} finally {

+			tt.done();

+		}

+			

+	}

+

+	@ApiDoc(   

+			method = GET,  

+			path = "/authn/certs/id/:id",

+			params = {"id|string|true"},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Return Cert Info for ID"

+				   }

+			)

+	@Override

+	public Result<CERTS> getCertInfoByID(AuthzTrans trans, HttpServletRequest req, String id) {

+		TimeTaken tt = trans.start("Get Cert Info by ID", Env.SUB);

+		try {			

+			CERTS certs = mapper.newInstance(API.CERTS);

+			Result<List<CertDAO.Data>> rlcd = ques.certDAO.readID(trans, id);

+					

+			if(rlcd.isOK()) {

+				if(!rlcd.isEmpty()) {

+					return mapper.cert(rlcd.value, certs);

+				}

+				return Result.ok(certs);		

+			} else { 

+				return Result.err(rlcd);

+			}

+		} finally {

+			tt.done();

+		}

+

+	}

+

+	@ApiDoc( 

+			method = PUT,  

+			path = "/authn/cred",

+			params = {},

+			expectedCode = 200,

+			errorCodes = {300,403,404,406}, 

+			text = { "Reset a Credential Password. If multiple credentials exist for this",

+						"ID, you will need to specify which entry you are resetting in the",

+						"CredRequest object"

+					 }

+			)

+	@Override

+	public Result<Void> changeUserCred(final AuthzTrans trans, REQUEST from) {

+		final String cmdDescription = "Update User Credential";

+		TimeTaken tt = trans.start(cmdDescription, Env.SUB);

+		try {

+			Result<CredDAO.Data> rcred = mapper.cred(trans, from, true);

+			if(rcred.isOKhasData()) {

+				rcred = ques.userCredSetup(trans, rcred.value);

+	

+				final Validator v = new Validator();

+				

+				if(v.cred(trans.org(),rcred,false).err()) {// Note: Creates have stricter Validations 

+					return Result.err(Status.ERR_BadData,v.errs());

+				}

+				Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, rcred.value.id);

+				if(rlcd.notOKorIsEmpty()) {

+					return Result.err(Status.ERR_UserNotFound, "Credential does not exist");

+				} 

+				

+				MayChange mc = new MayChangeCred(trans, rcred.value);

+				Result<?> rmc = mc.mayChange(); 

+				if (rmc.notOK()) {

+					return Result.err(rmc);

+				}

+				

+	 			Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);

+				if(ri.notOK()) {

+					return Result.err(ri);

+				}

+				int entry = ri.value;

+	

+				

+				final CredDAO.Data cred = rcred.value;

+				

+				Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from, rcred.value,false,

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return cmdDescription + " [" + 

+							cred.id + '|' 

+							+ cred.type + '|' 

+							+ cred.expires + ']';

+					}

+				},

+				mc);

+				

+				Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, rcred.value.ns);

+				if(nsr.notOKorIsEmpty()) {

+					return Result.err(nsr);

+				}

+	

+				switch(fd.status) {

+					case OK:

+						Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+								rcred.value.id + '|' + rcred.value.type.toString() + '|' + rcred.value.expires,

+								trans.user(), nsr.value.get(0), "U");

+						if(rfc.isOK()) {

+							return Result.err(Status.ACC_Future, "Credential Request [%s|%s|%s]",

+									rcred.value.id,

+									Integer.toString(rcred.value.type),

+									rcred.value.expires.toString());

+						} else { 

+							return Result.err(rfc);

+						}

+					case Status.ACC_Now:

+						Result<?>udr = null;

+						// If we are Resetting Password on behalf of someone else (am not the Admin)

+						//  use TempPassword Expiration time.

+						Expiration exp;

+						if(ques.isAdmin(trans, trans.user(), nsr.value.get(0).name)) {

+							exp = Expiration.Password;

+						} else {

+							exp = Expiration.TempPassword;

+						}

+						

+						Organization org = trans.org();

+						// If user resets password in same day, we will have a primary key conflict, so subtract 1 day

+						if (rlcd.value.get(entry).expires.equals(rcred.value.expires) 

+									&& rlcd.value.get(entry).type==rcred.value.type) {

+							GregorianCalendar gc = org.expiration(null, exp,rcred.value.id);

+							gc = Chrono.firstMomentOfDay(gc);

+							gc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());						

+							rcred.value.expires = new Date(gc.getTimeInMillis() - DAY_IN_MILLIS);

+						} else {

+							rcred.value.expires = org.expiration(null,exp).getTime();

+						}

+						

+						udr = ques.credDAO.create(trans, rcred.value);

+						if(udr.isOK()) {

+							udr = ques.credDAO.delete(trans, rlcd.value.get(entry),false);

+						}

+						if (udr.isOK()) {

+							return Result.ok();

+						}

+	

+						return Result.err(udr);

+					default:

+						return Result.err(fd);

+				}

+			} else {

+				return Result.err(rcred);

+			}

+		} finally {

+			tt.done();

+		}

+	}

+

+	/*

+	 * Codify the way to get Either Choice Needed or actual Integer from Credit Request

+	 */

+	private Result<Integer> selectEntryIfMultiple(final CredRequest cr, List<CredDAO.Data> lcd) {

+		int entry = 0;

+		if (lcd.size() > 1) {

+			String inputOption = cr.getEntry();

+			if (inputOption == null) {

+				String message = selectCredFromList(lcd, false);

+				String[] variables = buildVariables(lcd);

+				return Result.err(Status.ERR_ChoiceNeeded, message, variables);

+			} else {

+			    entry = Integer.parseInt(inputOption) - 1;

+			}

+			if (entry < 0 || entry >= lcd.size()) {

+				return Result.err(Status.ERR_BadData, "User chose invalid credential selection");

+			}

+		}

+		return Result.ok(entry);

+	}

+	

+	@ApiDoc( 

+			method = PUT,  

+			path = "/authn/cred/:days",

+			params = {"days|string|true"},

+			expectedCode = 200,

+			errorCodes = {300,403,404,406}, 

+			text = { "Extend a Credential Expiration Date. The intention of this API is",

+						"to avoid an outage in PROD due to a Credential expiring before it",

+						"can be configured correctly. Measures are being put in place ",

+						"so that this is not abused."

+					 }

+			)

+	@Override

+	public Result<Void> extendUserCred(final AuthzTrans trans, REQUEST from, String days) {

+		TimeTaken tt = trans.start("Extend User Credential", Env.SUB);

+		try {

+			Result<CredDAO.Data> cred = mapper.cred(trans, from, false);

+			Organization org = trans.org();

+			final Validator v = new Validator();

+			if(v.notOK(cred).err() || 

+			   v.nullOrBlank(cred.value.id, "Invalid ID").err() ||

+			   v.user(org,cred.value.id).err())  {

+				 return Result.err(Status.ERR_BadData,v.errs());

+			}

+			

+			try {

+				String reason;

+				if ((reason=org.validate(trans, Policy.MAY_EXTEND_CRED_EXPIRES, new CassExecutor(trans,func)))!=null) {

+					return Result.err(Status.ERR_Policy,reason);

+				}

+			} catch (Exception e) {

+				String msg;

+				trans.error().log(e, msg="Could not contact Organization for User Validation");

+				return Result.err(Status.ERR_Denied, msg);

+			}

+	

+			// Get the list of Cred Entries

+			Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, cred.value.id);

+			if(rlcd.notOKorIsEmpty()) {

+				return Result.err(Status.ERR_UserNotFound, "Credential does not exist");

+			}

+

+			//Need to do the "Pick Entry" mechanism

+			Result<Integer> ri = selectEntryIfMultiple((CredRequest)from, rlcd.value);

+			if(ri.notOK()) {

+				return Result.err(ri);

+			}

+

+			CredDAO.Data found = rlcd.value.get(ri.value);

+			CredDAO.Data cd = cred.value;

+			// Copy over the cred

+			cd.cred = found.cred;

+			cd.type = found.type;

+			cd.expires = org.expiration(null, Expiration.ExtendPassword,days).getTime();

+			

+			cred = ques.credDAO.create(trans, cd);

+			if(cred.isOK()) {

+				return Result.ok();

+			}

+			return Result.err(cred);

+		} finally {

+			tt.done();

+		}

+	}	

+

+	private String[] buildVariables(List<CredDAO.Data> value) {

+		// ensure credentials are sorted so we can fully automate Cred regression test

+		Collections.sort(value, new Comparator<CredDAO.Data>() {

+			@Override

+			public int compare(CredDAO.Data cred1, CredDAO.Data cred2) {

+				return cred1.expires.compareTo(cred2.expires);

+			}			

+		});

+		String [] vars = new String[value.size()+1];

+		vars[0]="Choice";

+		for (int i = 0; i < value.size(); i++) {

+		vars[i+1] = value.get(i).id + "    " + value.get(i).type 

+				+ "    |" + value.get(i).expires;

+		}

+		return vars;

+	}

+	

+	private String selectCredFromList(List<CredDAO.Data> value, boolean isDelete) {

+		StringBuilder errMessage = new StringBuilder();

+		String userPrompt = isDelete?"Select which cred to delete (set force=true to delete all):":"Select which cred to update:";

+		int numSpaces = value.get(0).id.length() - "Id".length();

+		

+		errMessage.append(userPrompt + '\n');

+		errMessage.append("       Id");

+		for (int i = 0; i < numSpaces; i++) {

+		    errMessage.append(' ');

+		}

+		errMessage.append("   Type  Expires" + '\n');

+		for(int i=0;i<value.size();++i) {

+			errMessage.append("    %s\n");

+		}

+		errMessage.append("Run same command again with chosen entry as last parameter");

+		

+		return errMessage.toString();

+		

+	}

+

+	@ApiDoc( 

+			method = DELETE,  

+			path = "/authn/cred",

+			params = {},

+			expectedCode = 200,

+			errorCodes = {300,403,404,406}, 

+			text = { "Delete a Credential. If multiple credentials exist for this",

+					"ID, you will need to specify which entry you are deleting in the",

+					"CredRequest object."

+					 }

+			)

+	@Override

+	public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST from)  {

+		final Result<CredDAO.Data> cred = mapper.cred(trans, from, false);

+		final Validator v = new Validator();

+		if(v.nullOrBlank("cred", cred.value.id).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+	

+		Result<List<CredDAO.Data>> rlcd = ques.credDAO.readID(trans, cred.value.id);

+		if(rlcd.notOKorIsEmpty()) {

+			// Empty Creds should have no user_roles.

+			Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id);

+			if(rlurd.isOK()) {

+				for(UserRoleDAO.Data data : rlurd.value) {

+					ques.userRoleDAO.delete(trans, data, false);

+				}

+			}

+			return Result.err(Status.ERR_UserNotFound, "Credential does not exist");

+		}

+		boolean isLastCred = rlcd.value.size()==1;

+		

+		MayChange mc = new MayChangeCred(trans,cred.value);

+		Result<?> rmc = mc.mayChange(); 

+		if (rmc.notOK()) {

+			return Result.err(rmc);

+		}

+		

+		int entry = 0;

+		if(!trans.forceRequested()) {

+			if (rlcd.value.size() > 1) {

+				CredRequest cr = (CredRequest)from;

+				String inputOption = cr.getEntry();

+				if (inputOption == null) {

+					String message = selectCredFromList(rlcd.value, true);

+					String[] variables = buildVariables(rlcd.value);

+					return Result.err(Status.ERR_ChoiceNeeded, message, variables);

+				} else {

+					try {

+						entry = Integer.parseInt(inputOption) - 1;

+					} catch(NumberFormatException e) {

+						return Result.err(Status.ERR_BadData, "User chose invalid credential selection");

+					}

+				}

+				isLastCred = (entry==-1)?true:false;

+			} else {

+				isLastCred = true;

+			}

+			if (entry < -1 || entry >= rlcd.value.size()) {

+				return Result.err(Status.ERR_BadData, "User chose invalid credential selection");

+			}

+		}

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans,CredDAO.TABLE,from,cred.value,false, 

+			new Mapper.Memo() {

+				@Override

+				public String get() {

+					return "Delete Credential [" + 

+						cred.value.id + 

+						']';

+				}

+			},

+			mc);

+	

+		Result<List<NsDAO.Data>> nsr = ques.nsDAO.read(trans, cred.value.ns);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);

+		}

+	

+		switch(fd.status) {

+			case OK:

+				Result<List<Identity>> rfc = func.createFuture(trans, fd.value, cred.value.id,

+						trans.user(), nsr.value.get(0),"D");

+	

+				if(rfc.isOK()) {

+					return Result.err(Status.ACC_Future, "Credential Delete [%s] is saved for future processing",cred.value.id);

+				} else { 

+					return Result.err(rfc);

+				}

+			case Status.ACC_Now:

+				Result<?>udr = null;

+				if (!trans.forceRequested()) {

+					if(entry<0 || entry >= rlcd.value.size()) {

+						return Result.err(Status.ERR_BadData,"Invalid Choice [" + entry + "] chosen for Delete [%s] is saved for future processing",cred.value.id);

+					}

+					udr = ques.credDAO.delete(trans, rlcd.value.get(entry),false);

+				} else {

+					for (CredDAO.Data curr : rlcd.value) {

+						udr = ques.credDAO.delete(trans, curr, false);

+						if (udr.notOK()) {

+							return Result.err(udr);

+						}

+					}

+				}

+				if(isLastCred) {

+					Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, cred.value.id);

+					if(rlurd.isOK()) {

+						for(UserRoleDAO.Data data : rlurd.value) {

+							ques.userRoleDAO.delete(trans, data, false);

+						}

+					}

+				}

+				if (udr.isOK()) {

+					return Result.ok();

+				}

+				return Result.err(udr);

+			default:

+				return Result.err(fd);

+		}

+	

+	}

+

+

+	@Override

+	public Result<Date> doesCredentialMatch(AuthzTrans trans, REQUEST credReq) {

+		TimeTaken tt = trans.start("Does Credential Match", Env.SUB);

+		try {

+			// Note: Mapper assigns RAW type

+			Result<CredDAO.Data> data = mapper.cred(trans, credReq,false);

+			if(data.notOKorIsEmpty()) {

+				return Result.err(data);

+			}

+			CredDAO.Data cred = data.value;	// of the Mapped Cred

+			return ques.doesUserCredMatch(trans, cred.id, cred.cred.array());

+

+		} catch (DAOException e) {

+			trans.error().log(e,"Error looking up cred");

+			return Result.err(Status.ERR_Denied,"Credential does not match");

+		} finally {

+			tt.done();

+		}

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authn/basicAuth",

+			params = {},

+			expectedCode = 200,

+			errorCodes = { 403 }, 

+			text = { "Validate a Password using BasicAuth Base64 encoded Header. This HTTP/S call is intended as a fast"

+					+ " User/Password lookup for Security Frameworks, and responds 200 if it passes BasicAuth "

+					+ "security, and 403 if it does not." }

+			)

+	private void basicAuth() {

+		// This is a place holder for Documentation.  The real BasicAuth API does not call Service.

+	}

+	

+	@ApiDoc( 

+			method = POST,  

+			path = "/authn/validate",

+			params = {},

+			expectedCode = 200,

+			errorCodes = { 403 }, 

+			text = { "Validate a Credential given a Credential Structure.  This is a more comprehensive validation, can "

+					+ "do more than BasicAuth as Credential types exp" }

+			)

+	@Override

+	public Result<Date> validateBasicAuth(AuthzTrans trans, String basicAuth) {

+		//TODO how to make sure people don't use this in browsers?  Do we care?

+		TimeTaken tt = trans.start("Validate Basic Auth", Env.SUB);

+		try {

+			BasicPrincipal bp = new BasicPrincipal(basicAuth,trans.org().getRealm());

+			Result<Date> rq = ques.doesUserCredMatch(trans, bp.getName(), bp.getCred());

+			// Note: Only want to log problem, don't want to send back to end user

+			if(rq.isOK()) {

+				return rq;

+			} else {

+				trans.audit().log(rq.errorString());

+			}

+		} catch (Exception e) {

+			trans.warn().log(e);

+		} finally {

+			tt.done();

+		}

+		return Result.err(Status.ERR_Denied,"Bad Basic Auth");

+	}

+

+/***********************************

+ * USER-ROLE 

+ ***********************************/

+	@ApiDoc( 

+			method = POST,  

+			path = "/authz/userRole",

+			params = {},

+			expectedCode = 201,

+			errorCodes = {403,404,406,409}, 

+			text = { "Create a UserRole relationship (add User to Role)",

+					 "A UserRole is an object Representation of membership of a Role for limited time.",

+					 "If a shorter amount of time for Role ownership is required, use the 'End' field.",

+					 "** Note: Owners of Namespaces will be required to revalidate users in these roles ",

+					 "before Expirations expire.  Namespace owners will be notified by email."

+				   }

+			)

+	@Override

+	public Result<Void> createUserRole(final AuthzTrans trans, REQUEST from) {

+		TimeTaken tt = trans.start("Create UserRole", Env.SUB);

+		try {

+			Result<UserRoleDAO.Data> urr = mapper.userRole(trans, from);

+			if(urr.notOKorIsEmpty()) {

+				return Result.err(urr);

+			}

+			final UserRoleDAO.Data userRole = urr.value;

+			

+			final Validator v = new Validator();

+			if(v.user_role(userRole).err() ||

+			   v.user(trans.org(), userRole.user).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+

+

+			 

+			// Check if user can change first

+			Result<FutureDAO.Data> fd = mapper.future(trans,UserRoleDAO.TABLE,from,urr.value,true, // may request Approvals

+				new Mapper.Memo() {

+					@Override

+					public String get() {

+						return "Add User [" + userRole.user + "] to Role [" + 

+								userRole.role + 

+								']';

+					}

+				},

+				new MayChange() {

+					private Result<NsDAO.Data> nsd;

+					@Override

+					public Result<?> mayChange() {

+						if(nsd==null) {

+							RoleDAO.Data r = RoleDAO.Data.decode(userRole);

+							nsd = ques.mayUser(trans, trans.user(), r, Access.write);

+						}

+						return nsd;

+					}

+				});

+			Result<NsDAO.Data> nsr = ques.deriveNs(trans, userRole.role);

+			if(nsr.notOKorIsEmpty()) {

+				return Result.err(nsr);

+			}

+

+			switch(fd.status) {

+				case OK:

+					Result<List<Identity>> rfc = func.createFuture(trans, fd.value, userRole.user+'|'+userRole.ns + '.' + userRole.rname, 

+							userRole.user, nsr.value, "C");

+					if(rfc.isOK()) {

+						return Result.err(Status.ACC_Future, "UserRole [%s - %s.%s] is saved for future processing",

+								userRole.user,

+								userRole.ns,

+								userRole.rname);

+					} else { 

+						return Result.err(rfc);

+					}

+				case Status.ACC_Now:

+					return func.addUserRole(trans, userRole);

+				default:

+					return Result.err(fd);

+			}

+		} finally {

+			tt.done();

+		}

+	}

+	

+		/**

+		 * getUserRolesByRole

+		 */

+	    @ApiDoc(

+	            method = GET,

+	            path = "/authz/userRoles/role/:role",

+	            params = {"role|string|true"},

+	            expectedCode = 200,

+	            errorCodes = {404,406},

+	            text = { "List all Users that are attached to Role specified in :role",

+	            		}

+	           )

+		@Override

+		public Result<USERROLES> getUserRolesByRole(AuthzTrans trans, String role) {

+			final Validator v = new Validator(trans);

+			if(v.nullOrBlank("Role",role).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+			

+			Result<RoleDAO.Data> rrdd;

+			rrdd = RoleDAO.Data.decode(trans,ques,role);

+			if(rrdd.notOK()) {

+				return Result.err(rrdd);

+			}

+			// May Requester see result?

+			Result<NsDAO.Data> ns = ques.mayUser(trans,trans.user(), rrdd.value,Access.read);

+			if (ns.notOK()) {

+				return Result.err(ns);

+			}

+	

+	//		boolean filter = true;		

+	//		if (ns.value.isAdmin(trans.user()) || ns.value.isResponsible(trans.user()))

+	//			filter = false;

+			

+			// Get list of roles per user, then add to Roles as we go

+			HashSet<UserRoleDAO.Data> userSet = new HashSet<UserRoleDAO.Data>();

+			Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role);

+			if(rlurd.isOK()) {

+				for(UserRoleDAO.Data data : rlurd.value) {

+					userSet.add(data);

+				}

+			}

+			

+			@SuppressWarnings("unchecked")

+			USERROLES users = (USERROLES) mapper.newInstance(API.USER_ROLES);

+			// Checked for permission

+			mapper.userRoles(trans, userSet, users);

+			return Result.ok(users);

+		}

+		/**

+		 * getUserRolesByRole

+		 */

+	    @ApiDoc(

+	            method = GET,

+	            path = "/authz/userRoles/user/:user",

+	            params = {"role|string|true"},

+	            expectedCode = 200,

+	            errorCodes = {404,406},

+	            text = { "List all UserRoles for :user",

+	            		}

+	           )

+		@Override

+		public Result<USERROLES> getUserRolesByUser(AuthzTrans trans, String user) {

+			final Validator v = new Validator(trans);

+			if(v.nullOrBlank("User",user).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+

+			// Get list of roles per user, then add to Roles as we go

+			Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, user);

+			if(rlurd.notOK()) { 

+				return Result.err(rlurd);

+			}

+			@SuppressWarnings("unchecked")

+			USERROLES users = (USERROLES) mapper.newInstance(API.USER_ROLES);

+			// Checked for permission

+			mapper.userRoles(trans, rlurd.value, users);

+			return Result.ok(users);

+		}

+

+	    

+	@ApiDoc( 

+			method = PUT,  

+			path = "/authz/userRole/user",

+			params = {},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Set a User's roles to the roles specified in the UserRoleRequest object.",

+						"WARNING: Roles supplied will be the ONLY roles attached to this user",

+						"If no roles are supplied, user's roles are reset."

+				   }

+			)

+	@Override

+	public Result<Void> resetRolesForUser(AuthzTrans trans, REQUEST rreq) {

+		Result<UserRoleDAO.Data> rurdd = mapper.userRole(trans, rreq);

+		final Validator v = new Validator();

+		if(rurdd.notOKorIsEmpty()) {

+			return Result.err(rurdd);

+		}

+		if (v.user(trans.org(), rurdd.value.user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Set<String> currRoles = new HashSet<String>();

+		Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByUser(trans, rurdd.value.user);

+		if(rlurd.isOK()) {

+			for(UserRoleDAO.Data data : rlurd.value) {

+				currRoles.add(data.role);

+			}

+		}

+		

+		Result<Void> rv = null;

+		String[] roles;

+		if(rurdd.value.role==null) {

+			roles = new String[0];

+		} else {

+			roles = rurdd.value.role.split(",");

+		}

+		

+		for (String role : roles) {			

+			if (v.role(role).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+			Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);

+			if(rrdd.notOK()) {

+				return Result.err(rrdd);

+			}

+			

+			rurdd.value.role(rrdd.value);

+			

+			Result<NsDAO.Data> nsd = ques.mayUser(trans, trans.user(), rrdd.value,Access.write);

+			if (nsd.notOK()) {

+				return Result.err(nsd);

+			}

+			Result<NsDAO.Data> nsr = ques.deriveNs(trans, role);

+			if(nsr.notOKorIsEmpty()) {

+				return Result.err(nsr);	

+			}

+			

+			if(currRoles.contains(role)) {

+				currRoles.remove(role);

+			} else {

+				rv = func.addUserRole(trans, rurdd.value);

+				if (rv.notOK()) {

+					return rv;

+				}

+			}

+		}

+		

+		for (String role : currRoles) {

+			rurdd.value.role(trans,ques,role);

+			rv = ques.userRoleDAO.delete(trans, rurdd.value, true);

+			if(rv.notOK()) {

+				trans.info().log(rurdd.value.user,"/",rurdd.value.role, "expected to be deleted, but does not exist");

+				// return rv; // if it doesn't exist, don't error out

+			}

+

+		}

+	

+		return Result.ok();		

+		

+	}

+	

+	@ApiDoc( 

+			method = PUT,  

+			path = "/authz/userRole/role",

+			params = {},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Set a Role's users to the users specified in the UserRoleRequest object.",

+					"WARNING: Users supplied will be the ONLY users attached to this role",

+					"If no users are supplied, role's users are reset."

+			   }

+			)

+	@Override

+	public Result<Void> resetUsersForRole(AuthzTrans trans, REQUEST rreq) {

+		Result<UserRoleDAO.Data> rurdd = mapper.userRole(trans, rreq);

+		if(rurdd.notOKorIsEmpty()) {

+			return Result.err(rurdd);

+		}

+		final Validator v = new Validator();

+		if (v.user_role(rurdd.value).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		RoleDAO.Data rd = RoleDAO.Data.decode(rurdd.value);

+

+		Result<NsDAO.Data> nsd = ques.mayUser(trans, trans.user(), rd, Access.write);

+		if (nsd.notOK()) {

+			return Result.err(nsd);

+		}

+

+		Result<NsDAO.Data> nsr = ques.deriveNs(trans, rurdd.value.role);

+		if(nsr.notOKorIsEmpty()) {

+			return Result.err(nsr);	

+		}

+

+		Set<String> currUsers = new HashSet<String>();

+		Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, rurdd.value.role);

+		if(rlurd.isOK()) { 

+			for(UserRoleDAO.Data data : rlurd.value) {

+				currUsers.add(data.user);

+			}

+		}

+	

+		// found when connected remotely to DEVL, can't replicate locally

+		// inconsistent errors with cmd: role user setTo [nothing]

+		// deleteUserRole --> read --> get --> cacheIdx(?)

+		// sometimes returns idx for last added user instead of user passed in

+		// cache bug? 

+		

+		

+		Result<Void> rv = null;

+		String[] users = {};

+		if (rurdd.value.user != null) {

+		    users = rurdd.value.user.split(",");

+		}

+		

+		for (String user : users) {			

+			if (v.user(trans.org(), user).err()) {

+				return Result.err(Status.ERR_BadData,v.errs());

+			}

+			rurdd.value.user = user;

+

+			if(currUsers.contains(user)) {

+				currUsers.remove(user);

+			} else {

+				rv = func.addUserRole(trans, rurdd.value);

+				if (rv.notOK()) { 

+					return rv;

+				}

+			}

+		}

+		

+		for (String user : currUsers) {

+			rurdd.value.user = user; 

+			rv = ques.userRoleDAO.delete(trans, rurdd.value, true);

+			if(rv.notOK()) {

+				trans.info().log(rurdd.value, "expected to be deleted, but not exists");

+				return rv;

+			}

+		}	

+		

+		return Result.ok();			

+	}

+	

+	@ApiDoc(

+	        method = GET,

+	        path = "/authz/userRole/extend/:user/:role",

+	        params = {	"user|string|true",

+	        			"role|string|true"

+	        		},

+	        expectedCode = 200,

+	        errorCodes = {403,404,406},

+	        text = { "Extend the Expiration of this User Role by the amount set by Organization",

+	        		 "Requestor must be allowed to modify the role"

+	        		}

+	       )

+	@Override

+	public Result<Void> extendUserRole(AuthzTrans trans, String user, String role) {

+		Organization org = trans.org();

+		final Validator v = new Validator();

+		if(v.user(org, user)

+			.role(role)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+	

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,ques,role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+		

+		Result<NsDAO.Data> rcr = ques.mayUser(trans, trans.user(), rrdd.value, Access.write);

+		boolean mayNotChange;

+		if((mayNotChange = rcr.notOK()) && !trans.futureRequested()) {

+			return Result.err(rcr);

+		}

+		

+		Result<List<UserRoleDAO.Data>> rr = ques.userRoleDAO.read(trans, user,role);

+		if(rr.notOK()) {

+			return Result.err(rr);

+		}

+		for(UserRoleDAO.Data userRole : rr.value) {

+			if(mayNotChange) { // Function exited earlier if !trans.futureRequested

+				FutureDAO.Data fto = new FutureDAO.Data();

+				fto.target=UserRoleDAO.TABLE;

+				fto.memo = "Extend User ["+userRole.user+"] in Role ["+userRole.role+"]";

+				GregorianCalendar now = new GregorianCalendar();

+				fto.start = now.getTime();

+				fto.expires = org.expiration(now, Expiration.Future).getTime();

+				try {

+					fto.construct = userRole.bytify();

+				} catch (IOException e) {

+					trans.error().log(e, "Error while bytifying UserRole for Future");

+					return Result.err(e);

+				}

+

+				Result<List<Identity>> rfc = func.createFuture(trans, fto, 

+						userRole.user+'|'+userRole.role, userRole.user, rcr.value, "U");

+				if(rfc.isOK()) {

+					return Result.err(Status.ACC_Future, "UserRole [%s - %s] is saved for future processing",

+							userRole.user,

+							userRole.role);

+				} else {

+					return Result.err(rfc);

+				}

+			} else {

+				return func.extendUserRole(trans, userRole, false);

+			}

+		}

+		return Result.err(Result.ERR_NotFound,"This user and role doesn't exist");

+	}

+

+	@ApiDoc( 

+			method = DELETE,  

+			path = "/authz/userRole/:user/:role",

+			params = {	"user|string|true",

+						"role|string|true"

+					},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Remove Role :role from User :user."

+				   }

+			)

+	@Override

+	public Result<Void> deleteUserRole(AuthzTrans trans, String usr, String role) {

+		Validator val = new Validator();

+		if(val.nullOrBlank("User", usr)

+		      .nullOrBlank("Role", role).err()) {

+			return Result.err(Status.ERR_BadData, val.errs());

+		}

+

+		boolean mayNotChange;

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans,ques,role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+		

+		RoleDAO.Data rdd = rrdd.value;

+		// Make sure we don't delete the last owner

+		if(Question.OWNER.equals(rdd.name) && ques.countOwner(trans, usr, rdd.ns)<=1) {

+			return Result.err(Status.ERR_Denied,"You may not delete the last Owner of " + rdd.ns );

+		}

+		

+		Result<NsDAO.Data> rns = ques.mayUser(trans, trans.user(), rdd, Access.write);

+		if(mayNotChange=rns.notOK()) {

+			if(!trans.futureRequested()) {

+				return Result.err(rns);

+			}

+		}

+

+		Result<List<UserRoleDAO.Data>> rulr;

+		if((rulr=ques.userRoleDAO.read(trans, usr, role)).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_UserRoleNotFound, "User [ "+usr+" ] is not "

+					+ "Assigned to the Role [ " + role + " ]");

+		}

+

+		UserRoleDAO.Data userRole = rulr.value.get(0);

+		if(mayNotChange) { // Function exited earlier if !trans.futureRequested

+			FutureDAO.Data fto = new FutureDAO.Data();

+			fto.target=UserRoleDAO.TABLE;

+			fto.memo = "Remove User ["+userRole.user+"] from Role ["+userRole.role+"]";

+			GregorianCalendar now = new GregorianCalendar();

+			fto.start = now.getTime();

+			fto.expires = trans.org().expiration(now, Expiration.Future).getTime();

+

+			Result<List<Identity>> rfc = func.createFuture(trans, fto, 

+					userRole.user+'|'+userRole.role, userRole.user, rns.value, "D");

+			if(rfc.isOK()) {

+				return Result.err(Status.ACC_Future, "UserRole [%s - %s] is saved for future processing", 

+						userRole.user,

+						userRole.role);

+			} else { 

+				return Result.err(rfc);

+			}

+		} else {

+			return ques.userRoleDAO.delete(trans, rulr.value.get(0), false);

+		}

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/userRole/:user/:role",

+			params = {"user|string|true",

+					  "role|string|true"},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Returns the User (with Expiration date from listed User/Role) if it exists"

+				   }

+			)

+	@Override

+	public Result<USERS> getUserInRole(AuthzTrans trans, String user, String role) {

+		final Validator v = new Validator();

+		if(v.role(role).nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+//		Result<NsDAO.Data> ns = ques.deriveNs(trans, role);

+//		if (ns.notOK()) return Result.err(ns);

+//		

+//		Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), ns.value, Access.write);

+		// May calling user see by virtue of the Role

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+		Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), rrdd.value,Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+		

+		HashSet<UserRoleDAO.Data> userSet = new HashSet<UserRoleDAO.Data>();

+		Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readUserInRole(trans, user, role);

+		if(rlurd.isOK()) {

+			for(UserRoleDAO.Data data : rlurd.value) {

+				userSet.add(data);

+			}

+		}

+		

+		@SuppressWarnings("unchecked")

+		USERS users = (USERS) mapper.newInstance(API.USERS);

+		mapper.users(trans, userSet, users);

+		return Result.ok(users);

+	}

+

+	@ApiDoc( 

+			method = GET,  

+			path = "/authz/users/role/:role",

+			params = {"user|string|true",

+					  "role|string|true"},

+			expectedCode = 200,

+			errorCodes = {403,404,406}, 

+			text = { "Returns the User (with Expiration date from listed User/Role) if it exists"

+				   }

+			)

+	@Override

+	public Result<USERS> getUsersByRole(AuthzTrans trans, String role) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Role",role).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+//		Result<NsDAO.Data> ns = ques.deriveNs(trans, role);

+//		if (ns.notOK()) return Result.err(ns);

+//		

+//		Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), ns.value, Access.write);

+		// May calling user see by virtue of the Role

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+		Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), rrdd.value,Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd); 

+		}

+		

+		HashSet<UserRoleDAO.Data> userSet = new HashSet<UserRoleDAO.Data>();

+		Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role);

+		if(rlurd.isOK()) { 

+			for(UserRoleDAO.Data data : rlurd.value) {

+				userSet.add(data);

+			}

+		}

+		

+		@SuppressWarnings("unchecked")

+		USERS users = (USERS) mapper.newInstance(API.USERS);

+		mapper.users(trans, userSet, users);

+		return Result.ok(users);

+	}

+

+	/**

+	 * getUsersByPermission

+	 */

+    @ApiDoc(

+            method = GET,

+            path = "/authz/users/perm/:type/:instance/:action",

+            params = {	"type|string|true",

+            			"instance|string|true",

+            			"action|string|true"

+            		},

+            expectedCode = 200,

+            errorCodes = {404,406},

+            text = { "List all Users that have Permission specified by :type :instance :action",

+            		}

+           )

+	@Override

+	public Result<USERS> getUsersByPermission(AuthzTrans trans, String type, String instance, String action) {

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("Type",type)

+			.nullOrBlank("Instance",instance)

+			.nullOrBlank("Action",action)			

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<NsSplit> nss = ques.deriveNsSplit(trans, type);

+		if(nss.notOK()) {

+			return Result.err(nss);

+		}

+		

+		Result<List<NsDAO.Data>> nsd = ques.nsDAO.read(trans, nss.value.ns);

+		if (nsd.notOK()) {

+			return Result.err(nsd);

+		}

+		

+		boolean allInstance = ASTERIX.equals(instance);

+		boolean allAction = ASTERIX.equals(action);

+		// Get list of roles per Permission, 

+		// Then loop through Roles to get Users

+		// Note: Use Sets to avoid processing or responding with Duplicates

+		Set<String> roleUsed = new HashSet<String>();

+		Set<UserRoleDAO.Data> userSet = new HashSet<UserRoleDAO.Data>();

+		

+		if(!nss.isEmpty()) {

+			Result<List<PermDAO.Data>> rlp = ques.permDAO.readByType(trans, nss.value.ns, nss.value.name);

+			if(rlp.isOKhasData()) {

+				for(PermDAO.Data pd : rlp.value) {

+					if((allInstance || pd.instance.equals(instance)) && 

+							(allAction || pd.action.equals(action))) {

+						if(ques.mayUser(trans, trans.user(),pd,Access.read).isOK()) {

+							for(String role : pd.roles) {

+								if(!roleUsed.contains(role)) { // avoid evaluating Role many times

+									roleUsed.add(role);

+									Result<List<UserRoleDAO.Data>> rlurd = ques.userRoleDAO.readByRole(trans, role.replace('|', '.'));

+									if(rlurd.isOKhasData()) {

+									    for(UserRoleDAO.Data urd : rlurd.value) {

+									    	userSet.add(urd);

+									    }

+									}

+								}

+							}

+						}

+					}

+				}

+			}

+		}

+		@SuppressWarnings("unchecked")

+		USERS users = (USERS) mapper.newInstance(API.USERS);

+		mapper.users(trans, userSet, users);

+		return Result.ok(users);

+	}

+

+    /***********************************

+ * HISTORY 

+ ***********************************/	

+	@Override

+	public Result<HISTORY> getHistoryByUser(final AuthzTrans trans, String user, final int[] yyyymm, final int sort) {	

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("User",user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<NsDAO.Data> rnd;

+		// Users may look at their own data

+		 if(trans.user().equals(user)) {

+				// Users may look at their own data

+		 } else {

+			int at = user.indexOf('@');

+			if(at>=0 && trans.org().getRealm().equals(user.substring(at+1))) {

+				NsDAO.Data nsd  = new NsDAO.Data();

+				nsd.name = Question.domain2ns(user);

+				rnd = ques.mayUser(trans, trans.user(), nsd, Access.read);

+				if(rnd.notOK()) {

+					return Result.err(rnd);

+				}

+			} else {

+				rnd = ques.validNSOfDomain(trans, user);

+				if(rnd.notOK()) {

+					return Result.err(rnd);

+				}

+

+				rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+				if(rnd.notOK()) {

+					return Result.err(rnd);

+				}

+			}

+		 }

+		Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readByUser(trans, user, yyyymm);

+		if(resp.notOK()) {

+			return Result.err(resp);

+		}

+		return mapper.history(trans, resp.value,sort);

+	}

+

+	@Override

+	public Result<HISTORY> getHistoryByRole(AuthzTrans trans, String role, int[] yyyymm, final int sort) {

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("Role",role).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<RoleDAO.Data> rrdd = RoleDAO.Data.decode(trans, ques, role);

+		if(rrdd.notOK()) {

+			return Result.err(rrdd);

+		}

+		

+		Result<NsDAO.Data> rnd = ques.mayUser(trans, trans.user(), rrdd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd);

+		}

+		Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, role, "role", yyyymm); 

+		if(resp.notOK()) {

+			return Result.err(resp);

+		}

+		return mapper.history(trans, resp.value,sort);

+	}

+

+	@Override

+	public Result<HISTORY> getHistoryByPerm(AuthzTrans trans, String type, int[] yyyymm, final int sort) {

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("Type",type)

+			.err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		// May user see Namespace of Permission (since it's only one piece... we can't check for "is permission part of")

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans,type);

+		if(rnd.notOK()) {

+			return Result.err(rnd);

+		}

+		

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd);	

+		}

+		Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, type, "perm", yyyymm);

+		if(resp.notOK()) {

+			return Result.err(resp);

+		}

+		return mapper.history(trans, resp.value,sort);

+	}

+

+	@Override

+	public Result<HISTORY> getHistoryByNS(AuthzTrans trans, String ns, int[] yyyymm, final int sort) {

+		final Validator v = new Validator(trans);

+		if(v.nullOrBlank("NS",ns)

+			.err()) { 

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<NsDAO.Data> rnd = ques.deriveNs(trans,ns);

+		if(rnd.notOK()) {

+			return Result.err(rnd);

+		}

+		rnd = ques.mayUser(trans, trans.user(), rnd.value, Access.read);

+		if(rnd.notOK()) {

+			return Result.err(rnd);	

+		}

+

+		Result<List<HistoryDAO.Data>> resp = ques.historyDAO.readBySubject(trans, ns, "ns", yyyymm);

+		if(resp.notOK()) {

+			return Result.err(resp);

+		}

+		return mapper.history(trans, resp.value,sort);

+	}

+

+/***********************************

+ * DELEGATE 

+ ***********************************/

+	@Override

+	public Result<Void> createDelegate(final AuthzTrans trans, REQUEST base) {

+		return createOrUpdateDelegate(trans, base, Question.Access.create);

+	}

+

+	@Override

+	public Result<Void> updateDelegate(AuthzTrans trans, REQUEST base) {

+		return createOrUpdateDelegate(trans, base, Question.Access.write);

+	}

+

+

+	private Result<Void> createOrUpdateDelegate(final AuthzTrans trans, REQUEST base, final Access access) {

+		final Result<DelegateDAO.Data> rd = mapper.delegate(trans, base);

+		final Validator v = new Validator();

+		if(v.delegate(trans.org(),rd).err()) { 

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		final DelegateDAO.Data dd = rd.value;

+		

+		Result<List<DelegateDAO.Data>> ddr = ques.delegateDAO.read(trans, dd);

+		if(access==Access.create && ddr.isOKhasData()) {

+			return Result.err(Status.ERR_ConflictAlreadyExists, "[%s] already delegates to [%s]", dd.user, ddr.value.get(0).delegate);

+		} else if(access!=Access.create && ddr.notOKorIsEmpty()) { 

+			return Result.err(Status.ERR_NotFound, "[%s] does not have a Delegate Record to [%s].",dd.user,access.name());

+		}

+		Result<Void> rv = ques.mayUser(trans, dd, access);

+		if(rv.notOK()) {

+			return rv;

+		}

+		

+		Result<FutureDAO.Data> fd = mapper.future(trans,DelegateDAO.TABLE,base, dd, false, 

+			new Mapper.Memo() {

+				@Override

+				public String get() {

+					StringBuilder sb = new StringBuilder();

+					sb.append(access.name());

+					sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));

+					sb.append("Delegate ");

+					sb.append(access==Access.create?"[":"to [");

+					sb.append(rd.value.delegate);

+					sb.append("] for [");

+					sb.append(rd.value.user);

+					sb.append(']');

+					return sb.toString();

+				}

+			},

+			new MayChange() {

+				@Override

+				public Result<?> mayChange() {

+					return Result.ok(); // Validate in code above

+				}

+			});

+		

+		switch(fd.status) {

+			case OK:

+				Result<List<Identity>> rfc = func.createFuture(trans, fd.value, 

+						dd.user, trans.user(),null, access==Access.create?"C":"U");

+				if(rfc.isOK()) { 

+					return Result.err(Status.ACC_Future, "Delegate for [%s]",

+							dd.user);

+				} else { 

+					return Result.err(rfc);

+				}

+			case Status.ACC_Now:

+				if(access==Access.create) {

+					Result<DelegateDAO.Data> rdr = ques.delegateDAO.create(trans, dd);

+					if(rdr.isOK()) {

+						return Result.ok();

+					} else {

+						return Result.err(rdr);

+					}

+				} else {

+					return ques.delegateDAO.update(trans, dd);

+				}

+			default:

+				return Result.err(fd);

+		}

+	}

+

+	@Override

+	public Result<Void> deleteDelegate(AuthzTrans trans, REQUEST base) {

+		final Result<DelegateDAO.Data> rd = mapper.delegate(trans, base);

+		final Validator v = new Validator();

+		if(v.notOK(rd).nullOrBlank("User", rd.value.user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		Result<List<DelegateDAO.Data>> ddl;

+		if((ddl=ques.delegateDAO.read(trans, rd.value)).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate");

+		}

+		final DelegateDAO.Data dd = ddl.value.get(0);

+		Result<Void> rv = ques.mayUser(trans, dd, Access.write);

+		if(rv.notOK()) {

+			return rv;

+		}

+		

+		return ques.delegateDAO.delete(trans, dd, false);

+	}

+

+	@Override

+	public Result<Void> deleteDelegate(AuthzTrans trans, String userName) {

+		DelegateDAO.Data dd = new DelegateDAO.Data();

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", userName).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		dd.user = userName;

+		Result<List<DelegateDAO.Data>> ddl;

+		if((ddl=ques.delegateDAO.read(trans, dd)).notOKorIsEmpty()) {

+			return Result.err(Status.ERR_DelegateNotFound,"Cannot delete non-existent Delegate");

+		}

+		dd = ddl.value.get(0);

+		Result<Void> rv = ques.mayUser(trans, dd, Access.write);

+		if(rv.notOK()) {

+			return rv;

+		}

+		

+		return ques.delegateDAO.delete(trans, dd, false);

+	}

+	

+	@Override

+	public Result<DELGS> getDelegatesByUser(AuthzTrans trans, String user) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", user).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		DelegateDAO.Data ddd = new DelegateDAO.Data();

+		ddd.user = user;

+		ddd.delegate = null;

+		Result<Void> rv = ques.mayUser(trans, ddd, Access.read);

+		if(rv.notOK()) {

+			return Result.err(rv);

+		}

+		

+		TimeTaken tt = trans.start("Get delegates for a user", Env.SUB);

+

+		Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO.read(trans, user);

+		try {

+			if (dbDelgs.isOKhasData()) {

+				return mapper.delegate(dbDelgs.value);

+			} else {

+				return Result.err(Status.ERR_DelegateNotFound,"No Delegate found for [%s]",user);

+			}

+		} finally {

+			tt.done();

+		}		

+	}

+

+	@Override

+	public Result<DELGS> getDelegatesByDelegate(AuthzTrans trans, String delegate) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Delegate", delegate).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		DelegateDAO.Data ddd = new DelegateDAO.Data();

+		ddd.user = delegate;

+		Result<Void> rv = ques.mayUser(trans, ddd, Access.read);

+		if(rv.notOK()) {

+			return Result.err(rv);

+		}

+

+		TimeTaken tt = trans.start("Get users for a delegate", Env.SUB);

+

+		Result<List<DelegateDAO.Data>> dbDelgs = ques.delegateDAO.readByDelegate(trans, delegate);

+		try {

+			if (dbDelgs.isOKhasData()) {

+				return mapper.delegate(dbDelgs.value);

+			} else {

+				return Result.err(Status.ERR_DelegateNotFound,"Delegate [%s] is not delegating for anyone.",delegate);

+			}

+		} finally {

+			tt.done();

+		}		

+	}

+

+/***********************************

+ * APPROVAL 

+ ***********************************/

+	@Override

+	public Result<Void> updateApproval(AuthzTrans trans, APPROVALS approvals) {

+		Result<List<ApprovalDAO.Data>> rlad = mapper.approvals(approvals);

+		if(rlad.notOK()) {

+			return Result.err(rlad);

+		}

+		int numApprs = rlad.value.size();

+		if(numApprs<1) {

+			return Result.err(Status.ERR_NoApprovals,"No Approvals sent for Updating");

+		}

+		int numProcessed = 0;

+		String user = trans.user();

+		

+		Result<List<ApprovalDAO.Data>> curr;

+		for(ApprovalDAO.Data updt : rlad.value) {

+			if(updt.ticket!=null) {

+				curr = ques.approvalDAO.readByTicket(trans, updt.ticket);

+			} else if(updt.id!=null) {

+				curr = ques.approvalDAO.read(trans, updt);

+			} else if(updt.approver!=null) {

+				curr = ques.approvalDAO.readByApprover(trans, updt.approver);

+			} else {

+				return Result.err(Status.ERR_BadData,"Approvals need ID, Ticket or Approval data to update");

+			}

+			if(curr.isOKhasData()) {

+			    for(ApprovalDAO.Data cd : curr.value){

+			    	// Check for right record.  Need ID, or (Ticket&Trans.User==Appr)

+			    	// If Default ID

+			    	boolean delegatedAction = ques.isDelegated(trans, user, cd.approver);

+			    	String delegator = cd.approver;

+			    	if(updt.id!=null || 

+			    		(updt.ticket!=null && user.equals(cd.approver)) ||

+			    		(updt.ticket!=null && delegatedAction)) {

+			    		if(updt.ticket.equals(cd.ticket)) {

+			    			cd.id = changed(updt.id,cd.id);

+			    			cd.ticket = changed(updt.ticket,cd.ticket);

+			    			cd.user = changed(updt.user,cd.user);

+			    			cd.approver = changed(updt.approver,cd.approver);

+			    			cd.type = changed(updt.type,cd.type);

+			    			cd.status = changed(updt.status,cd.status);

+			    			cd.memo = changed(updt.memo,cd.memo);

+			    			cd.operation = changed(updt.operation,cd.operation);

+			    			cd.updated = changed(updt.updated,cd.updated);

+			    			ques.approvalDAO.update(trans, cd);

+			    			Result<Void> rv = func.performFutureOp(trans, cd);

+			    			if (rv.isOK()) {

+			    				if (delegatedAction) {

+			    					trans.audit().log("actor=",user,",action=",updt.status,",operation=\"",cd.memo,

+			    							'"',",requestor=",cd.user,",delegator=",delegator);

+			    				}

+			    				if (!delegatedAction && cd.status.equalsIgnoreCase("denied")) {

+			    					trans.audit().log("actor=",trans.user(),",action=denied,operation=\"",cd.memo,'"',",requestor=",cd.user);

+			    				}

+			    				rv = ques.approvalDAO.delete(trans, cd, false);

+			    			}

+			    			++numProcessed;

+

+			    		}

+			    	}

+			    }

+			}

+		}

+

+		if(numApprs==numProcessed) {

+			return Result.ok();

+		}

+		return Result.err(Status.ERR_ActionNotCompleted,numProcessed + " out of " + numApprs + " completed");

+

+	}

+	

+	private<T> T changed(T src, T dflt) {

+		if(src!=null) {

+		    return src;

+		}

+		return dflt;

+	}

+

+	@Override

+	public Result<APPROVALS> getApprovalsByUser(AuthzTrans trans, String user) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("User", user).err()) { 

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+

+		Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByUser(trans, user);

+		if(rapd.isOK()) {

+			return mapper.approvals(rapd.value);

+		} else {

+			return Result.err(rapd);

+		}

+}

+

+	@Override

+	public Result<APPROVALS> getApprovalsByTicket(AuthzTrans trans, String ticket) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Ticket", ticket).err()) { 

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		UUID uuid;

+		try {

+			uuid = UUID.fromString(ticket);

+		} catch (IllegalArgumentException e) {

+			return Result.err(Status.ERR_BadData,e.getMessage());

+		}

+	

+		Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByTicket(trans, uuid);

+		if(rapd.isOK()) {

+			return mapper.approvals(rapd.value);

+		} else {

+			return Result.err(rapd);

+		}

+	}

+	

+	@Override

+	public Result<APPROVALS> getApprovalsByApprover(AuthzTrans trans, String approver) {

+		final Validator v = new Validator();

+		if(v.nullOrBlank("Approver", approver).err()) {

+			return Result.err(Status.ERR_BadData,v.errs());

+		}

+		

+		List<ApprovalDAO.Data> listRapds = new ArrayList<ApprovalDAO.Data>();

+		

+		Result<List<ApprovalDAO.Data>> myRapd = ques.approvalDAO.readByApprover(trans, approver);

+		if(myRapd.notOK()) {

+			return Result.err(myRapd);

+		}

+		

+		listRapds.addAll(myRapd.value);

+		

+		Result<List<DelegateDAO.Data>> delegatedFor = ques.delegateDAO.readByDelegate(trans, approver);

+		if (delegatedFor.isOK()) {

+			for (DelegateDAO.Data dd : delegatedFor.value) {

+				if (dd.expires.after(new Date())) {

+					String delegator = dd.user;

+					Result<List<ApprovalDAO.Data>> rapd = ques.approvalDAO.readByApprover(trans, delegator);

+					if (rapd.isOK()) {

+						for (ApprovalDAO.Data d : rapd.value) { 

+							if (!d.user.equals(trans.user())) {

+								listRapds.add(d);

+							}

+						}

+					}

+				}

+			}

+		}

+		

+		return mapper.approvals(listRapds);

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#clearCache(org.onap.aaf.authz.env.AuthzTrans, java.lang.String)

+	 */

+	@Override

+	public Result<Void> cacheClear(AuthzTrans trans, String cname) {

+		if(ques.isGranted(trans,trans.user(),Define.ROOT_NS,CACHE,cname,"clear")) {

+			return ques.clearCache(trans,cname);

+		}

+		return Result.err(Status.ERR_Denied, "%s does not have AAF Permission '%s.cache|%s|clear",

+				trans.user(),Define.ROOT_NS,cname);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#cacheClear(org.onap.aaf.authz.env.AuthzTrans, java.lang.String, java.lang.Integer)

+	 */

+	@Override

+	public Result<Void> cacheClear(AuthzTrans trans, String cname, int[] segment) {

+		if(ques.isGranted(trans,trans.user(),Define.ROOT_NS,CACHE,cname,"clear")) {

+			Result<Void> v=null;

+			for(int i: segment) {

+				v=ques.cacheClear(trans,cname,i);

+			}

+			if(v!=null) {

+				return v;

+			}

+		}

+		return Result.err(Status.ERR_Denied, "%s does not have AAF Permission '%s.cache|%s|clear",

+				trans.user(),Define.ROOT_NS,cname);

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.AuthzService#dbReset(org.onap.aaf.authz.env.AuthzTrans)

+	 */

+	@Override

+	public void dbReset(AuthzTrans trans) {

+		ques.historyDAO.reportPerhapsReset(trans, null);

+	}

+

+}

+

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzService.java b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzService.java
new file mode 100644
index 0000000..27a000f
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/AuthzService.java
@@ -0,0 +1,748 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import java.util.Date;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.mapper.Mapper;

+import org.onap.aaf.dao.DAOException;

+import org.onap.aaf.dao.aaf.cass.NsType;

+

+public interface AuthzService<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> {

+	public Mapper<NSS,PERMS,PERMKEY,ROLES,USERS,USERROLES,DELGS,CERTS,KEYS,REQUEST,HISTORY,ERR,APPROVALS> mapper();

+	

+/***********************************

+ * NAMESPACE 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param ns

+	 * @return

+	 * @throws DAOException 

+	 * @throws  

+	 */

+	public Result<Void> createNS(AuthzTrans trans, REQUEST request, NsType type);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<Void> addAdminNS(AuthzTrans trans, String ns, String id);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<Void> delAdminNS(AuthzTrans trans, String ns, String id);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param id

+	 * @return

+	 */

+	public Result<Void> addResponsibleNS(AuthzTrans trans, String ns, String id);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param id

+	 * @return

+	 */

+	public Result<Void> delResponsibleNS(AuthzTrans trans, String ns, String id);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param key

+	 * @param value

+	 * @return

+	 */

+	public Result<Void> createNsAttrib(AuthzTrans trans, String ns, String key, String value);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param key

+	 * @param value

+	 * @return

+	 */

+	public Result<?> updateNsAttrib(AuthzTrans trans, String ns, String key, String value);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param key

+	 * @return

+	 */

+	public Result<Void> deleteNsAttrib(AuthzTrans trans, String ns, String key);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param key

+	 * @return

+	 */

+	public Result<KEYS> readNsByAttrib(AuthzTrans trans, String key);

+

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<NSS> getNSbyName(AuthzTrans trans, String ns);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<NSS> getNSbyAdmin(AuthzTrans trans, String user, boolean full);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<NSS> getNSbyResponsible(AuthzTrans trans, String user, boolean full);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<NSS> getNSbyEither(AuthzTrans trans, String user, boolean full);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param parent

+	 * @return

+	 */

+	public Result<NSS> getNSsChildren(AuthzTrans trans, String parent);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @return

+	 */

+	public Result<Void> updateNsDescription(AuthzTrans trans, REQUEST req);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @param user

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<Void> deleteNS(AuthzTrans trans, String ns);

+

+/***********************************

+ * PERM 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param rreq

+	 * @return

+	 * @throws DAOException 

+	 * @throws MappingException

+	 */

+	public Result<Void> createPerm(AuthzTrans trans, REQUEST rreq);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param childPerm

+	 * @return

+	 * @throws DAOException 

+	 */

+	public Result<PERMS> getPermsByType(AuthzTrans trans, String perm);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @return

+	 */

+	public Result<PERMS> getPermsByName(AuthzTrans trans, String type,

+			String instance, String action);

+

+	/**

+	 * Gets all the permissions for a user across all the roles it is assigned to

+	 * @param userName

+	 * @return

+	 * @throws Exception 

+	 * @throws Exception

+	 */

+	public Result<PERMS> getPermsByUser(AuthzTrans trans, String userName);

+

+	/**

+	 * Gets all the permissions for a user across all the roles it is assigned to

+	 * 

+	 * Add AAF Perms representing the "MayUser" calls if

+	 * 	1) Allowed

+	 *  2) User has equivalent permission

+	 * 	

+	 * @param userName

+	 * @return

+	 * @throws Exception 

+	 * @throws Exception

+	 */

+	public Result<PERMS> getPermsByUser(AuthzTrans trans, PERMS perms, String userName);

+

+	/**

+	 * 

+	 * Gets all the permissions for a user across all the roles it is assigned to

+	 * 

+	 * @param roleName

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<PERMS> getPermsByRole(AuthzTrans trans, String roleName);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<PERMS> getPermsByNS(AuthzTrans trans, String ns);

+

+	/**

+	 * rename permission

+	 * 

+	 * @param trans

+	 * @param rreq

+	 * @param isRename

+	 * @param origType

+	 * @param origInstance

+	 * @param origAction

+	 * @return

+	 */

+	public Result<Void> renamePerm(AuthzTrans trans, REQUEST rreq, String origType, String origInstance, String origAction);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @return

+	 */

+	public Result<Void> updatePermDescription(AuthzTrans trans, REQUEST req);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 */

+	public Result<Void> resetPermRoles(AuthzTrans trans, REQUEST from);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Void> deletePerm(AuthzTrans trans, REQUEST from);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param perm

+	 * @param type

+	 * @param action

+	 * @return

+	 * @throws Exception

+	 */

+	Result<Void> deletePerm(AuthzTrans trans, String perm, String type, String action);

+

+/***********************************

+ * ROLE 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param role

+	 * @param approvers

+	 * @return

+	 * @throws DAOException 

+	 * @throws Exception

+	 */

+	public Result<Void> createRole(AuthzTrans trans, REQUEST req);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param role

+	 * @return

+	 */

+	public Result<ROLES> getRolesByName(AuthzTrans trans, String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 * @throws DAOException 

+	 */

+	public Result<ROLES> getRolesByUser(AuthzTrans trans, String user);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<ROLES> getRolesByNS(AuthzTrans trans, String user);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param name

+	 * @return

+	 */

+	public Result<ROLES> getRolesByNameOnly(AuthzTrans trans, String name);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @return

+	 */

+	public Result<ROLES> getRolesByPerm(AuthzTrans trans, String type, String instance, String action);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @return

+	 */

+	public Result<Void> updateRoleDescription(AuthzTrans trans, REQUEST req);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param rreq

+	 * @return

+	 * @throws DAOException

+	 */

+	public Result<Void> addPermToRole(AuthzTrans trans, REQUEST rreq);

+	

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param rreq

+	 * @return

+	 * @throws DAOException

+	 */

+	Result<Void> delPermFromRole(AuthzTrans trans, REQUEST rreq);

+

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param role

+	 * @return

+	 * @throws DAOException 

+	 * @throws MappingException 

+	 */

+	public Result<Void> deleteRole(AuthzTrans trans, String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @return

+	 */

+	public Result<Void> deleteRole(AuthzTrans trans, REQUEST req);

+

+/***********************************

+ * CRED 

+ ***********************************/

+

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 */

+	Result<Void> createUserCred(AuthzTrans trans, REQUEST from);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 */

+	Result<Void> changeUserCred(AuthzTrans trans, REQUEST from);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @param days

+	 * @return

+	 */

+	Result<Void> extendUserCred(AuthzTrans trans, REQUEST from, String days);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ns

+	 * @return

+	 */

+	public Result<USERS> getCredsByNS(AuthzTrans trans, String ns);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param id

+	 * @return

+	 */

+	public Result<USERS> getCredsByID(AuthzTrans trans, String id);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param req

+	 * @param id

+	 * @return

+	 */

+	public Result<CERTS> getCertInfoByID(AuthzTrans trans, HttpServletRequest req, String id);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param credReq

+	 * @return

+	 */

+	public Result<Void> deleteUserCred(AuthzTrans trans, REQUEST credReq);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Date> doesCredentialMatch(AuthzTrans trans, REQUEST credReq);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param basicAuth

+	 * @return

+	 */

+	public Result<Date> validateBasicAuth(AuthzTrans trans, String basicAuth);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param role

+	 * @return

+	 */

+	public Result<USERS> getUsersByRole(AuthzTrans trans, String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param role

+	 * @return

+	 */

+	public Result<USERS> getUserInRole(AuthzTrans trans, String user, String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param type

+	 * @param instance

+	 * @param action

+	 * @return

+	 */

+	public Result<USERS> getUsersByPermission(AuthzTrans trans,String type, String instance, String action);

+	

+	

+

+

+/***********************************

+ * USER-ROLE 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param request

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Void> createUserRole(AuthzTrans trans, REQUEST request);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param role

+	 * @return

+	 */

+	public Result<USERROLES> getUserRolesByRole(AuthzTrans trans, String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param role

+	 * @return

+	 */

+	public Result<USERROLES> getUserRolesByUser(AuthzTrans trans, String user);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 */

+	public Result<Void> resetRolesForUser(AuthzTrans trans, REQUEST from);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param from

+	 * @return

+	 */

+	public Result<Void> resetUsersForRole(AuthzTrans trans, REQUEST from);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param role

+	 * @return

+	 */

+	public Result<Void> extendUserRole(AuthzTrans trans, String user,

+	String role);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param usr

+	 * @param role

+	 * @return

+	 * @throws DAOException 

+	 */

+	public Result<Void> deleteUserRole(AuthzTrans trans, String usr, String role);

+

+

+

+/***********************************

+ * HISTORY 

+ ***********************************/	

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param yyyymm

+	 * @return

+	 */

+	public Result<HISTORY> getHistoryByUser(AuthzTrans trans, String user, int[] yyyymm, int sort);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param subj

+	 * @param yyyymm

+	 * @param sort

+	 * @return

+	 */

+	public Result<HISTORY> getHistoryByRole(AuthzTrans trans, String subj, int[] yyyymm, int sort);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param subj

+	 * @param yyyymm

+	 * @param sort

+	 * @return

+	 */

+	public Result<HISTORY> getHistoryByPerm(AuthzTrans trans, String subj, int[] yyyymm, int sort);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param subj

+	 * @param yyyymm

+	 * @param sort

+	 * @return

+	 */

+	public Result<HISTORY> getHistoryByNS(AuthzTrans trans, String subj, int[] yyyymm, int sort);

+

+/***********************************

+ * DELEGATE 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param delegates

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Void> createDelegate(AuthzTrans trans, REQUEST reqDelegate);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param delegates

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Void> updateDelegate(AuthzTrans trans, REQUEST reqDelegate);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param userName

+	 * @param delegate

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<Void> deleteDelegate(AuthzTrans trans, REQUEST reqDelegate);

+	

+	/**

+	 * 

+	 * @param trans

+	 * @param userName

+	 * @return

+	 */

+	public Result<Void> deleteDelegate(AuthzTrans trans, String userName);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 * @throws Exception

+	 */

+	public Result<DELGS> getDelegatesByUser(AuthzTrans trans, String user);

+	

+

+	/**

+	 * 

+	 * @param trans

+	 * @param delegate

+	 * @return

+	 */

+	public Result<DELGS> getDelegatesByDelegate(AuthzTrans trans, String delegate);

+

+/***********************************

+ * APPROVAL 

+ ***********************************/

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @param approver

+	 * @param status

+	 * @return

+	 */

+	public Result<Void> updateApproval(AuthzTrans trans, APPROVALS approvals);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param user

+	 * @return

+	 */

+	public Result<APPROVALS> getApprovalsByUser(AuthzTrans trans, String user);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param ticket

+	 * @return

+	 */

+	public Result<APPROVALS> getApprovalsByTicket(AuthzTrans trans, String ticket);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param approver

+	 * @return

+	 */

+	public Result<APPROVALS> getApprovalsByApprover(AuthzTrans trans, String approver);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param cname

+	 * @return

+	 */

+	public Result<Void> cacheClear(AuthzTrans trans, String cname);

+

+	/**

+	 * 

+	 * @param trans

+	 * @param cname

+	 * @param segment

+	 * @return

+	 */

+	public Result<Void> cacheClear(AuthzTrans trans, String cname, int[] segment);

+

+	/**

+	 * 

+	 * @param trans

+	 */

+	public void dbReset(AuthzTrans trans);

+

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/Code.java b/authz-service/src/main/java/org/onap/aaf/authz/service/Code.java
new file mode 100644
index 0000000..097b6da
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/Code.java
@@ -0,0 +1,45 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.cssa.rserv.HttpCode;

+

+public abstract class Code extends HttpCode<AuthzTrans, AuthzFacade> implements Cloneable {

+	public boolean useJSON;

+

+	public Code(AuthzFacade facade, String description, boolean useJSON, String ... roles) {

+		super(facade, description, roles);

+		this.useJSON = useJSON;

+	}

+	

+	public <D extends Code> D clone(AuthzFacade facade, boolean useJSON) throws Exception {

+		@SuppressWarnings("unchecked")

+		D d = (D)clone();

+		d.useJSON = useJSON;

+		d.context = facade;

+		return d;

+	}

+	

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/MayChange.java b/authz-service/src/main/java/org/onap/aaf/authz/service/MayChange.java
new file mode 100644
index 0000000..f697af5
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/MayChange.java
@@ -0,0 +1,33 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import org.onap.aaf.authz.layer.Result;

+

+/**

+ * There are several ways to determine if 

+ *

+ */

+public interface MayChange {

+	public Result<?> mayChange();

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Api.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Api.java
new file mode 100644
index 0000000..128096c
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Api.java
@@ -0,0 +1,93 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.Symm;

+

+/**

+ * API Apis

+ *

+ */

+public class API_Api {

+	// Hide Public Constructor

+	private API_Api() {}

+	

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		////////

+		// Overall APIs

+		///////

+		authzAPI.route(HttpMethods.GET,"/api",API.API,new Code(facade,"Document API", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getAPI(trans,resp,authzAPI);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		////////

+		// Overall Examples

+		///////

+		authzAPI.route(HttpMethods.GET,"/api/example/*",API.VOID,new Code(facade,"Document API", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String pathInfo = req.getPathInfo();

+				int question = pathInfo.lastIndexOf('?');

+				

+				pathInfo = pathInfo.substring(13, question<0?pathInfo.length():question);// IMPORTANT, this is size of "/api/example/"

+				String nameOrContextType=Symm.base64noSplit.decode(pathInfo);

+				Result<Void> r = context.getAPIExample(trans,resp,nameOrContextType,

+						question>=0 && "optional=true".equalsIgnoreCase(req.getPathInfo().substring(question+1))

+						);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Approval.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Approval.java
new file mode 100644
index 0000000..f69e6f7
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Approval.java
@@ -0,0 +1,108 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+public class API_Approval {

+	// Hide Public Constructor

+	private API_Approval() {}

+	

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+

+		/**

+		 * Get Approvals by User

+		 */

+		authzAPI.route(GET, "/authz/approval/user/:user",API.APPROVALS,

+				new Code(facade,"Get Approvals by User", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getApprovalsByUser(trans, resp, pathParam(req,"user"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200); 

+				} else {

+					context.error(trans,resp,r);

+				}				

+			}			

+		});

+

+		/**

+		 * Get Approvals by Ticket

+		 */

+		authzAPI.route(GET, "/authz/approval/ticket/:ticket",API.VOID,new Code(facade,"Get Approvals by Ticket ", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getApprovalsByTicket(trans, resp, pathParam(req,"ticket"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}				

+			}			

+		});

+

+		/**

+		 * Get Approvals by Approver

+		 */

+		authzAPI.route(GET, "/authz/approval/approver/:approver",API.APPROVALS,new Code(facade,"Get Approvals by Approver", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getApprovalsByApprover(trans, resp, pathParam(req,"approver"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+

+

+		/**

+		 * Update an approval

+		 */

+		authzAPI.route(PUT, "/authz/approval",API.APPROVALS,new Code(facade,"Update approvals", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.updateApproval(trans, req, resp);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}				

+			}			

+		});

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Creds.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Creds.java
new file mode 100644
index 0000000..7c1425b
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Creds.java
@@ -0,0 +1,278 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import java.security.Principal;

+import java.util.Date;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.cadi.DirectAAFUserPass;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.cssa.rserv.HttpMethods;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.CredVal;

+import org.onap.aaf.cadi.Symm;

+import org.onap.aaf.cadi.principal.BasicPrincipal;

+import org.onap.aaf.cadi.principal.X509Principal;

+import org.onap.aaf.inno.env.Env;

+

+/**

+ * Initialize All Dispatches related to Credentials (AUTHN)

+ *

+ */

+public class API_Creds {

+	// Hide Public Interface

+	private API_Creds() {}

+	// needed to validate Creds even when already Authenticated x509

+	/**

+	 * TIME SENSITIVE APIs

+	 * 

+	 * These will be first in the list

+	 * 

+	 * @param env

+	 * @param authzAPI

+	 * @param facade

+	 * @param directAAFUserPass 

+	 * @throws Exception

+	 */

+	public static void timeSensitiveInit(Env env, AuthAPI authzAPI, AuthzFacade facade, final DirectAAFUserPass directAAFUserPass) throws Exception {

+		/**

+		 * Basic Auth, quick Validation

+		 * 

+		 * Responds OK or NotAuthorized

+		 */

+		authzAPI.route(env, HttpMethods.GET, "/authn/basicAuth", new Code(facade,"Is given BasicAuth valid?",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+

+				Principal p = trans.getUserPrincipal();

+				if (p instanceof BasicPrincipal) {

+					// the idea is that if call is made with this credential, and it's a BasicPrincipal, it's ok

+					// otherwise, it wouldn't have gotten here.

+					resp.setStatus(HttpStatus.OK_200);

+				} else if (p instanceof X509Principal) {

+					// have to check Basic Auth here, because it might be CSP.

+					String ba = req.getHeader("Authorization");

+					if(ba.startsWith("Basic ")) {

+						String decoded = Symm.base64noSplit.decode(ba.substring(6));

+						int colon = decoded.indexOf(':');

+						if(directAAFUserPass.validate(

+								decoded.substring(0,colon), 

+								CredVal.Type.PASSWORD , 

+								decoded.substring(colon+1).getBytes())) {

+							

+							resp.setStatus(HttpStatus.OK_200);

+						} else {

+							resp.setStatus(HttpStatus.FORBIDDEN_403);

+						}

+					}

+				} else if(p == null) {

+					trans.error().log("Transaction not Authenticated... no Principal");

+					resp.setStatus(HttpStatus.FORBIDDEN_403);

+				} else {

+					trans.checkpoint("Basic Auth Check Failed: This wasn't a Basic Auth Trans");

+					// For Auth Security questions, we don't give any info to client on why failed

+					resp.setStatus(HttpStatus.FORBIDDEN_403);

+				}

+			}

+		},"text/plain");

+		

+		/** 

+		 *  returns whether a given Credential is valid

+		 */

+		authzAPI.route(POST, "/authn/validate", API.CRED_REQ, new Code(facade,"Is given Credential valid?",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Date> r = context.doesCredentialMatch(trans, req, resp);

+				if(r.isOK()) {

+						resp.setStatus(HttpStatus.OK_200);

+				} else {

+						// For Security, we don't give any info out on why failed, other than forbidden

+						resp.setStatus(HttpStatus.FORBIDDEN_403);

+				}

+			}

+		});  

+

+		/** 

+		 *  returns whether a given Credential is valid

+		 */

+		authzAPI.route(GET, "/authn/cert/id/:id", API.CERTS, new Code(facade,"Get Cert Info by ID",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getCertInfoByID(trans, req, resp, pathParam(req,":id") );

+				if(r.isOK()) {

+						resp.setStatus(HttpStatus.OK_200); 

+				} else {

+						// For Security, we don't give any info out on why failed, other than forbidden

+						resp.setStatus(HttpStatus.FORBIDDEN_403);

+				}

+			}

+		});  

+

+

+

+

+	}

+	

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * Create a new ID/Credential

+		 */

+		authzAPI.route(POST,"/authn/cred",API.CRED_REQ,new Code(facade,"Add a New ID/Credential", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.createUserCred(trans, req);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.CREATED_201);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/** 

+		 *  gets all credentials by Namespace

+		 */

+		authzAPI.route(GET, "/authn/creds/ns/:ns", API.USERS, new Code(facade,"Get Creds for a Namespace",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getCredsByNS(trans, resp, pathParam(req, "ns"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200); 

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+

+		});

+		

+		/** 

+		 *  gets all credentials by ID

+		 */

+		authzAPI.route(GET, "/authn/creds/id/:id", API.USERS, new Code(facade,"Get Creds by ID",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getCredsByID(trans, resp, pathParam(req, "id"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200); 

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+

+		});

+

+

+		/**

+		 * Update ID/Credential (aka reset)

+		 */

+		authzAPI.route(PUT,"/authn/cred",API.CRED_REQ,new Code(facade,"Update an ID/Credential", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.changeUserCred(trans, req);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Extend ID/Credential

+		 * This behavior will accelerate getting out of P1 outages due to ignoring renewal requests, or

+		 * other expiration issues.

+		 * 

+		 * Scenario is that people who are solving Password problems at night, are not necessarily those who

+		 * know what the passwords are supposed to be.  Also, changing Password, without changing Configurations

+		 * using that password only exacerbates the P1 Issue.

+		 */

+		authzAPI.route(PUT,"/authn/cred/:days",API.CRED_REQ,new Code(facade,"Extend an ID/Credential", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.extendUserCred(trans, req, pathParam(req, "days"));

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Delete a ID/Credential by Object

+		 */

+		authzAPI.route(DELETE,"/authn/cred",API.CRED_REQ,new Code(facade,"Delete a Credential", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteUserCred(trans, req);

+				if(r.isOK()) {

+					resp.setStatus(HttpStatus.OK_200);

+				} else {

+					context.error(trans,resp,r);

+				}

+			}

+		});

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Delegate.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Delegate.java
new file mode 100644
index 0000000..6d382c5
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Delegate.java
@@ -0,0 +1,154 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+public class API_Delegate {

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * Add a delegate

+		 */

+		authzAPI.route(POST, "/authz/delegate",API.DELG_REQ,new Code(facade,"Add a Delegate", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.createDelegate(trans, req, resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.CREATED_201); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+		

+		/**

+		 * Update a delegate

+		 */

+		authzAPI.route(PUT, "/authz/delegate",API.DELG_REQ,new Code(facade,"Update a Delegate", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.updateDelegate(trans, req, resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+		

+		/**

+		 * DELETE delegates for a user

+		 */

+		authzAPI.route(DELETE, "/authz/delegate",API.DELG_REQ,new Code(facade,"Delete delegates for a user", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteDelegate(trans, req, resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+		

+		/**

+		 * DELETE a delegate

+		 */

+		authzAPI.route(DELETE, "/authz/delegate/:user_name",API.VOID,new Code(facade,"Delete a Delegate", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteDelegate(trans, pathParam(req, "user_name"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+		

+		/**

+		 * Read who is delegating for User

+		 */

+		authzAPI.route(GET, "/authz/delegates/user/:user",API.DELGS,new Code(facade,"Get Delegates by User", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getDelegatesByUser(trans, pathParam(req, "user"), resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+

+		/**

+		 * Read for whom the User is delegating

+		 */

+		authzAPI.route(GET, "/authz/delegates/delegate/:delegate",API.DELGS,new Code(facade,"Get Delegates by Delegate", true) {

+

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getDelegatesByDelegate(trans, pathParam(req, "delegate"), resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}				

+			}			

+		});

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_History.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_History.java
new file mode 100644
index 0000000..d9db889
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_History.java
@@ -0,0 +1,239 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Date;

+import java.util.GregorianCalendar;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+/**

+ * Pull certain types of History Info

+ * 

+ * Specify yyyymm as 

+ * 	single - 201504

+ *  commas 201503,201504

+ *  ranges 201501-201504

+ *  combinations 201301,201401,201501-201504

+ *  

+ *

+ */

+public class API_History {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * Get History

+		 */

+		authzAPI.route(GET,"/authz/hist/user/:user",API.HISTORY,new Code(facade,"Get History by User", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				int[] years;

+				int descend;

+				try {

+					years = getYears(req);

+					descend = decending(req);

+				} catch(Exception e) {

+					context.error(trans, resp, Result.err(Status.ERR_BadData, e.getMessage()));

+					return;

+				}

+

+				Result<Void> r = context.getHistoryByUser(trans, resp, pathParam(req,":user"),years,descend);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Get History by NS

+		 */

+		authzAPI.route(GET,"/authz/hist/ns/:ns",API.HISTORY,new Code(facade,"Get History by Namespace", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				int[] years;

+				int descend;

+				try {

+					years = getYears(req);

+					descend = decending(req);

+				} catch(Exception e) {

+					context.error(trans, resp, Result.err(Status.ERR_BadData, e.getMessage()));

+					return;

+				}

+				

+				Result<Void> r = context.getHistoryByNS(trans, resp, pathParam(req,":ns"),years,descend);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Get History by Role

+		 */

+		authzAPI.route(GET,"/authz/hist/role/:role",API.HISTORY,new Code(facade,"Get History by Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				int[] years;

+				int descend;

+				try {

+					years = getYears(req);

+					descend = decending(req);

+				} catch(Exception e) {

+					context.error(trans, resp, Result.err(Status.ERR_BadData, e.getMessage()));

+					return;

+				}

+

+				Result<Void> r = context.getHistoryByRole(trans, resp, pathParam(req,":role"),years,descend);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Get History by Perm Type

+		 */

+		authzAPI.route(GET,"/authz/hist/perm/:type",API.HISTORY,new Code(facade,"Get History by Perm Type", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				int[] years;

+				int descend;

+				try {

+					years = getYears(req);

+					descend = decending(req);

+				} catch(Exception e) {

+					context.error(trans, resp, Result.err(Status.ERR_BadData, e.getMessage()));

+					return;

+				}

+				

+				Result<Void> r = context.getHistoryByPerm(trans, resp, pathParam(req,":type"),years,descend);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+	}

+

+	// Check if Ascending

+	private static int decending(HttpServletRequest req) {

+		if("true".equalsIgnoreCase(req.getParameter("desc")))return -1;

+		if("true".equalsIgnoreCase(req.getParameter("asc")))return 1;

+		return 0;

+	}

+	

+	// Get Common "yyyymm" parameter, or none

+	private static final SimpleDateFormat FMT = new SimpleDateFormat("yyyyMM");

+	

+	private static int[] getYears(HttpServletRequest req) throws NumberFormatException {

+		String yyyymm = req.getParameter("yyyymm");

+		ArrayList<Integer> ai= new ArrayList<Integer>();

+		if(yyyymm==null) {

+			GregorianCalendar gc = new GregorianCalendar();

+			// three months is the default

+			for(int i=0;i<3;++i) {

+				ai.add(Integer.parseInt(FMT.format(gc.getTime())));

+				gc.add(GregorianCalendar.MONTH, -1);

+			}

+		} else {

+			for(String ym : yyyymm.split(",")) {

+				String range[] = ym.split("\\s*-\\s*");

+				switch(range.length) {

+					case 0:

+						break;

+					case 1:

+						if(!ym.endsWith("-")) {

+							ai.add(getNum(ym));

+							break;

+						} else {

+							range=new String[] {ym.substring(0, 6),FMT.format(new Date())};

+						}

+					default:

+						GregorianCalendar gc = new GregorianCalendar();

+						gc.set(GregorianCalendar.MONTH, Integer.parseInt(range[1].substring(4,6))-1);

+						gc.set(GregorianCalendar.YEAR, Integer.parseInt(range[1].substring(0,4)));

+						int end = getNum(FMT.format(gc.getTime())); 

+						

+						gc.set(GregorianCalendar.MONTH, Integer.parseInt(range[0].substring(4,6))-1);

+						gc.set(GregorianCalendar.YEAR, Integer.parseInt(range[0].substring(0,4)));

+						for(int i=getNum(FMT.format(gc.getTime()));i<=end;gc.add(GregorianCalendar.MONTH, 1),i=getNum(FMT.format(gc.getTime()))) {

+							ai.add(i);

+						}

+

+				}

+			}

+		}

+		if(ai.size()==0) {

+			throw new NumberFormatException(yyyymm + " is an invalid number or range");

+		}

+		Collections.sort(ai);

+		int ym[] = new int[ai.size()];

+		for(int i=0;i<ym.length;++i) {

+			ym[i]=ai.get(i);

+		}

+		return ym;

+	}

+	

+	private static int getNum(String n) {

+		if(n==null || n.length()!=6) throw new NumberFormatException(n + " is not in YYYYMM format");

+		return Integer.parseInt(n);

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Mgmt.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Mgmt.java
new file mode 100644
index 0000000..90ee6be
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Mgmt.java
@@ -0,0 +1,275 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.common.Define;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.onap.aaf.dao.session.SessionFilter;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.taf.dos.DenialOfServiceTaf;

+import org.onap.aaf.inno.env.Trans;

+

+/**

+ * User Role APIs

+ *

+ */

+public class API_Mgmt {

+

+	private static final String SUCCESS = "SUCCESS";

+

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+

+		/**

+		 * Clear Cache Segment

+		 */

+		authzAPI.route(DELETE,"/mgmt/cache/:area/:segments",API.VOID,new Code(facade,"Clear Cache by Segment", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.cacheClear(trans, pathParam(req,"area"), pathParam(req,"segments"));

+				switch(r.status) {

+					case OK:

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Clear Cache

+		 */

+		authzAPI.route(DELETE,"/mgmt/cache/:area",API.VOID,new Code(facade,"Clear Cache", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r;

+				String area;

+				r = context.cacheClear(trans, area=pathParam(req,"area"));

+				switch(r.status) {

+					case OK:

+						trans.audit().log("Cache " + area + " has been cleared by "+trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Clear DB Sessions

+		 */

+		authzAPI.route(DELETE,"/mgmt/dbsession",API.VOID,new Code(facade,"Clear DBSessions", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				try {

+					if(req.isUserInRole(Define.ROOT_NS+".db|pool|clear")) {

+						SessionFilter.clear();

+						context.dbReset(trans);

+

+						trans.audit().log("DB Sessions have been cleared by "+trans.user());

+

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200);

+						return;

+					}

+					context.error(trans,resp,Result.err(Result.ERR_Denied,"%s is not allowed to clear dbsessions",trans.user()));

+				} catch(Exception e) {

+					trans.error().log(e, "clearing dbsession");

+					context.error(trans,resp,Result.err(e));

+				}

+			}

+		});

+

+		/**

+		 * Deny an IP 

+		 */

+		authzAPI.route(POST, "/mgmt/deny/ip/:ip", API.VOID, new Code(facade,"Deny IP",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String ip = pathParam(req,":ip");

+				if(req.isUserInRole(Define.ROOT_NS+".deny|"+Define.ROOT_COMPANY+"|ip")) {

+					if(DenialOfServiceTaf.denyIP(ip)) {

+						trans.audit().log(ip+" has been set to deny by "+trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+

+						resp.setStatus(HttpStatus.CREATED_201);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_ConflictAlreadyExists, 

+								ip + " is already being denied"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to deny",ip,"without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to set IP Denial"));

+				}

+			}

+		});

+		

+		/**

+		 * Stop Denying an IP

+		 */

+		authzAPI.route(DELETE, "/mgmt/deny/ip/:ip", API.VOID, new Code(facade,"Stop Denying IP",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String ip = pathParam(req,":ip");

+				if(req.isUserInRole(Define.ROOT_NS+".deny|"+Define.ROOT_COMPANY+"|ip")) {

+					if(DenialOfServiceTaf.removeDenyIP(ip)) {

+						trans.audit().log(ip+" has been removed from denial by "+trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_NotFound, 

+								ip + " is not on the denial list"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to remove",ip," from being denied without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to remove IP Denial"));

+				}

+			}

+		});

+

+		/**

+		 * Deny an ID 

+		 */

+		authzAPI.route(POST, "/mgmt/deny/id/:id", API.VOID, new Code(facade,"Deny ID",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String id = pathParam(req,":id");

+				if(req.isUserInRole(Define.ROOT_NS+".deny|"+Define.ROOT_COMPANY+"|id")) {

+					if(DenialOfServiceTaf.denyID(id)) {

+						trans.audit().log(id+" has been set to deny by "+trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.CREATED_201);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_ConflictAlreadyExists, 

+								id + " is already being denied"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to deny",id,"without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to set ID Denial"));

+				}

+			}

+		});

+		

+		/**

+		 * Stop Denying an ID

+		 */

+		authzAPI.route(DELETE, "/mgmt/deny/id/:id", API.VOID, new Code(facade,"Stop Denying ID",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String id = pathParam(req,":id");

+				if(req.isUserInRole(Define.ROOT_NS+".deny|"+Define.ROOT_COMPANY+"|id")) {

+					if(DenialOfServiceTaf.removeDenyID(id)) {

+						trans.audit().log(id+" has been removed from denial by " + trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_NotFound, 

+								id + " is not on the denial list"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to remove",id," from being denied without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to remove ID Denial"));

+				}

+			}

+		});

+

+		/**

+		 * Deny an ID 

+		 */

+		authzAPI.route(POST, "/mgmt/log/id/:id", API.VOID, new Code(facade,"Special Log ID",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String id = pathParam(req,":id");

+				if(req.isUserInRole(Define.ROOT_NS+".log|"+Define.ROOT_COMPANY+"|id")) {

+					if(Question.specialLogOn(trans,id)) {

+						trans.audit().log(id+" has been set to special Log by "+trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.CREATED_201);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_ConflictAlreadyExists, 

+								id + " is already being special Logged"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to special Log",id,"without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to set ID special Logging"));

+				}

+			}

+		});

+		

+		/**

+		 * Stop Denying an ID

+		 */

+		authzAPI.route(DELETE, "/mgmt/log/id/:id", API.VOID, new Code(facade,"Stop Special Log ID",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				String id = pathParam(req,":id");

+				if(req.isUserInRole(Define.ROOT_NS+".log|"+Define.ROOT_COMPANY+"|id")) {

+					if(Question.specialLogOff(trans,id)) {

+						trans.audit().log(id+" has been removed from special Logging by " + trans.user());

+						trans.checkpoint(SUCCESS,Trans.ALWAYS);

+						resp.setStatus(HttpStatus.OK_200);

+					} else {

+						context.error(trans,resp,Result.err(Status.ERR_NotFound, 

+								id + " is not on the special Logging list"));

+					}

+				} else {

+					trans.audit().log(trans.user(),"has attempted to remove",id," from being special Logged without authorization");

+					context.error(trans,resp,Result.err(Status.ERR_Denied, 

+						trans.getUserPrincipal().getName() + " is not allowed to remove ID special Logging"));

+				}

+			}

+		});

+

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_NS.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_NS.java
new file mode 100644
index 0000000..d92302c
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_NS.java
@@ -0,0 +1,397 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+public class API_NS {

+	private static final String FULL = "full";

+	private static final String TRUE = "true";

+

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * puts a new Namespace in Authz DB

+		 * 

+		 * TESTCASES: TC_NS1, TC_NSdelete1

+		 */

+		authzAPI.route(POST,"/authz/ns",API.NS_REQ, new Code(facade,"Create a Namespace",true) {

+					@Override

+					public void handle(

+							AuthzTrans trans,

+							HttpServletRequest req, 

+							HttpServletResponse resp) throws Exception {

+						NsType nst = NsType.fromString(req.getParameter("type"));

+						Result<Void> r = context.requestNS(trans, req, resp,nst);

+							

+						switch(r.status) {

+							case OK:

+								resp.setStatus(HttpStatus.CREATED_201); 

+								break;

+							case Status.ACC_Future:

+								resp.setStatus(HttpStatus.ACCEPTED_202); 

+								break;

+							default:

+								context.error(trans,resp,r);

+						}

+					}

+				}

+		);

+		

+		/**

+		 * removes a Namespace from Authz DB

+		 * 

+		 * TESTCASES: TC_NS1, TC_NSdelete1

+		 */

+		authzAPI.route(DELETE,"/authz/ns/:ns",API.VOID, new Code(facade,"Delete a Namespace",true) {

+				@Override

+				public void handle(

+						AuthzTrans trans,

+						HttpServletRequest req, 

+						HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.deleteNS(trans, req, resp, pathParam(req,":ns"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		/**

+		 * Add an Admin in NS in Authz DB

+		 * 

+		 * TESTCASES: TC_NS1

+		 */

+		authzAPI.route(POST,"/authz/ns/:ns/admin/:id",API.VOID, new Code(facade,"Add an Admin to a Namespace",true) {

+			@Override

+			public void handle(

+				AuthzTrans trans,

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.addAdminToNS(trans, resp, pathParam(req,":ns"), pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.CREATED_201); 

+							break;

+						case Status.ACC_Future:

+							resp.setStatus(HttpStatus.ACCEPTED_202); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+	

+		/**

+		 * Removes an Admin from Namespace in Authz DB

+		 * 

+		 * TESTCASES: TC_NS1

+		 */

+		authzAPI.route(DELETE,"/authz/ns/:ns/admin/:id",API.VOID, new Code(facade,"Remove an Admin from a Namespace",true) {

+			@Override

+			public void handle(

+				AuthzTrans trans,

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.delAdminFromNS(trans, resp, pathParam(req,":ns"), pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+	/**

+	 * Add an Admin in NS in Authz DB

+	 * 

+	 * TESTCASES: TC_NS1

+	 */

+		authzAPI.route(POST,"/authz/ns/:ns/responsible/:id",API.VOID, new Code(facade,"Add a Responsible Identity to a Namespace",true) {

+			@Override

+			public void handle(

+				AuthzTrans trans,

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.addResponsibilityForNS(trans, resp, pathParam(req,":ns"), pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.CREATED_201); 

+							break;

+						case Status.ACC_Future:

+							resp.setStatus(HttpStatus.ACCEPTED_202); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+

+		/**

+		 * 

+		 */

+		authzAPI.route(GET,"/authz/nss/:id",API.NSS, new Code(facade,"Return Information about Namespaces", true) {

+			@Override

+			public void handle(

+				AuthzTrans trans, 

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getNSsByName(trans, resp, pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);	

+		

+		/**

+		 * Get all Namespaces where user is an admin

+		 */

+		authzAPI.route(GET,"/authz/nss/admin/:user",API.NSS, new Code(facade,"Return Namespaces where User is an Admin", true) {

+			@Override

+			public void handle(

+				AuthzTrans trans, 

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getNSsByAdmin(trans, resp, pathParam(req,":user"),TRUE.equals(req.getParameter(FULL)));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+		

+		/**

+		 * Get all Namespaces where user is a responsible party

+		 */

+		authzAPI.route(GET,"/authz/nss/responsible/:user",API.NSS, new Code(facade,"Return Namespaces where User is Responsible", true) {

+			@Override

+			public void handle(

+				AuthzTrans trans, 

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getNSsByResponsible(trans, resp, pathParam(req,":user"),TRUE.equals(req.getParameter(FULL)));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		/**

+		 * Get all Namespaces where user is an admin or owner

+		 */

+		authzAPI.route(GET,"/authz/nss/either/:user",API.NSS, new Code(facade,"Return Namespaces where User Admin or Owner", true) {

+			@Override

+			public void handle(

+				AuthzTrans trans, 

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getNSsByEither(trans, resp, pathParam(req,":user"),TRUE.equals(req.getParameter(FULL)));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		/**

+		 * Get all children Namespaces

+		 */

+		authzAPI.route(GET,"/authz/nss/children/:id",API.NSS, new Code(facade,"Return Child Namespaces", true) {

+			@Override

+			public void handle(

+				AuthzTrans trans, 

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.getNSsChildren(trans, resp, pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		/**

+		 * Set a description of a Namespace

+		 */

+		authzAPI.route(PUT,"/authz/ns",API.NS_REQ,new Code(facade,"Set a Description for a Namespace",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.updateNsDescription(trans, req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});	

+	

+		/**

+		 * Removes an Owner from Namespace in Authz DB

+		 * 

+		 * TESTCASES: TC_NS1

+		 */

+		authzAPI.route(DELETE,"/authz/ns/:ns/responsible/:id",API.VOID, new Code(facade,"Remove a Responsible Identity from Namespace",true) {

+			@Override

+			public void handle(

+				AuthzTrans trans,

+				HttpServletRequest req, 

+				HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.delResponsibilityForNS(trans, resp, pathParam(req,":ns"), pathParam(req,":id"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		authzAPI.route(POST,"/authz/ns/:ns/attrib/:key/:value",API.VOID, new Code(facade,"Add an Attribute from a Namespace",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.createAttribForNS(trans, resp, 

+						pathParam(req,":ns"), 

+						pathParam(req,":key"),

+						pathParam(req,":value"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.CREATED_201); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		authzAPI.route(GET,"/authz/ns/attrib/:key",API.KEYS, new Code(facade,"get Ns Key List From Attribute",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.readNsByAttrib(trans, resp, pathParam(req,":key"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+		authzAPI.route(PUT,"/authz/ns/:ns/attrib/:key/:value",API.VOID, new Code(facade,"update an Attribute from a Namespace",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.updAttribForNS(trans, resp, 

+						pathParam(req,":ns"), 

+						pathParam(req,":key"),

+						pathParam(req,":value"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+		

+		authzAPI.route(DELETE,"/authz/ns/:ns/attrib/:key",API.VOID, new Code(facade,"delete an Attribute from a Namespace",true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.delAttribForNS(trans, resp, 

+						pathParam(req,":ns"), 

+						pathParam(req,":key"));

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+

+	}

+	

+	

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Perms.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Perms.java
new file mode 100644
index 0000000..793bba1
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Perms.java
@@ -0,0 +1,292 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import java.net.URLDecoder;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+import org.onap.aaf.cadi.config.Config;

+

+public class API_Perms {

+	public static void timeSensitiveInit(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/** 

+		 *  gets all permissions by user name

+		 */

+		authzAPI.route(GET, "/authz/perms/user/:user", API.PERMS, new Code(facade,"Get Permissions by User",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsByUser(trans, resp, pathParam(req, "user"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+		

+		/** 

+		 *  gets all permissions by user name

+		 */

+		authzAPI.route(POST, "/authz/perms/user/:user", API.PERMS, new Code(facade,"Get Permissions by User, Query AAF Perms",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsByUserWithAAFQuery(trans, req, resp, pathParam(req, "user"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+

+

+	} // end timeSensitiveInit

+

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * Create a Permission

+		 */

+		authzAPI.route(POST,"/authz/perm",API.PERM_REQ,new Code(facade,"Create a Permission",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.createPerm(trans, req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.CREATED_201); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/** 

+		 *  get details of Permission

+		 */

+		authzAPI.route(GET, "/authz/perms/:type/:instance/:action", API.PERMS, new Code(facade,"Get Permissions by Key",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsByName(trans, resp, 

+						pathParam(req, "type"),

+						URLDecoder.decode(pathParam(req, "instance"),Config.UTF_8),

+						pathParam(req, "action"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+		

+		/** 

+		 *  get children of Permission

+		 */

+		authzAPI.route(GET, "/authz/perms/:type", API.PERMS, new Code(facade,"Get Permissions by Type",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsByType(trans, resp, pathParam(req, "type"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+

+		

+		/**

+		 * gets all permissions by role name

+		 */

+		authzAPI.route(GET,"/authz/perms/role/:role",API.PERMS,new Code(facade,"Get Permissions by Role",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsForRole(trans, resp, pathParam(req, "role"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * gets all permissions by Namespace

+		 */

+		authzAPI.route(GET,"/authz/perms/ns/:ns",API.PERMS,new Code(facade,"Get PermsByNS",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getPermsByNS(trans, resp, pathParam(req, "ns"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Set a perm's description

+		 */

+		authzAPI.route(PUT,"/authz/perm",API.PERM_REQ,new Code(facade,"Set Description for Permission",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.updatePermDescription(trans, req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});	

+		

+		/**

+		 * Update a permission with a rename

+		 */

+		authzAPI.route(PUT,"/authz/perm/:type/:instance/:action",API.PERM_REQ,new Code(facade,"Update a Permission",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.renamePerm(trans, req, resp, pathParam(req, "type"), 

+						pathParam(req, "instance"), pathParam(req, "action"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});	

+		

+		/**

+		 * Delete a Permission

+		 */

+		authzAPI.route(DELETE,"/authz/perm",API.PERM_REQ,new Code(facade,"Delete a Permission",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.deletePerm(trans,req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		

+		

+

+		/**

+		 * Delete a Permission

+		 */

+		authzAPI.route(DELETE,"/authz/perm/:name/:type/:action",API.PERM_KEY,new Code(facade,"Delete a Permission",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.deletePerm(trans, resp,

+						pathParam(req, ":name"),

+						pathParam(req, ":type"),

+						pathParam(req, ":action"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+	} // end init

+}

+

+

+

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Roles.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Roles.java
new file mode 100644
index 0000000..1669c4a
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_Roles.java
@@ -0,0 +1,314 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+import org.onap.aaf.dao.aaf.cass.Status;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+public class API_Roles {

+	public static void init(AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * puts a new role in Authz DB

+		 */

+		authzAPI.route(POST,"/authz/role",API.ROLE_REQ, new Code(facade,"Create Role",true) {

+					@Override

+					public void handle(

+							AuthzTrans trans,

+							HttpServletRequest req, 

+							HttpServletResponse resp) throws Exception {

+						Result<Void> r = context.createRole(trans, req, resp);

+							

+						switch(r.status) {

+							case OK:

+								resp.setStatus(HttpStatus.CREATED_201); 

+								break;

+							case Status.ACC_Future:

+								resp.setStatus(HttpStatus.ACCEPTED_202); 

+								break;

+							default:

+								context.error(trans,resp,r);

+						}

+					}

+				}

+			);

+

+		/** 

+		 *  get Role by name

+		 */

+		authzAPI.route(GET, "/authz/roles/:role", API.ROLES, new Code(facade,"GetRolesByFullName",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getRolesByName(trans, resp, pathParam(req, "role"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+

+

+		/** 

+		 *  gets all Roles by user name

+		 */

+		authzAPI.route(GET, "/authz/roles/user/:name", API.ROLES, new Code(facade,"GetRolesByUser",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getRolesByUser(trans, resp, pathParam(req, "name"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+

+		});

+

+		/** 

+		 *  gets all Roles by Namespace

+		 */

+		authzAPI.route(GET, "/authz/roles/ns/:ns", API.ROLES, new Code(facade,"GetRolesByNS",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getRolesByNS(trans, resp, pathParam(req, "ns"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/** 

+		 *  gets all Roles by Name without the Namespace

+		 */

+		authzAPI.route(GET, "/authz/roles/name/:name", API.ROLES, new Code(facade,"GetRolesByNameOnly",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getRolesByNameOnly(trans, resp, pathParam(req, ":name"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Deletes a Role from Authz DB by Object

+		 */

+		authzAPI.route(DELETE,"/authz/role",API.ROLE_REQ, new Code(facade,"Delete Role",true) {

+				@Override

+				public void handle(

+						AuthzTrans trans,

+						HttpServletRequest req, 

+						HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.deleteRole(trans, req, resp);

+					

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			

+			}

+		);

+	

+

+		

+		/**

+		 * Deletes a Role from Authz DB by Key

+		 */

+		authzAPI.route(DELETE,"/authz/role/:role",API.ROLE, new Code(facade,"Delete Role",true) {

+				@Override

+				public void handle(

+						AuthzTrans trans,

+						HttpServletRequest req, 

+						HttpServletResponse resp) throws Exception {

+					Result<Void> r = context.deleteRole(trans, resp, pathParam(req,":role"));

+						

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.OK_200); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			

+			}

+		);

+	

+

+		/**

+		 * Add a Permission to a Role (Grant)

+		 */

+		authzAPI.route(POST,"/authz/role/perm",API.ROLE_PERM_REQ, new Code(facade,"Add Permission to Role",true) {

+				@Override

+				public void handle(

+						AuthzTrans trans,

+						HttpServletRequest req, 

+						HttpServletResponse resp) throws Exception {

+					

+					Result<Void> r = context.addPermToRole(trans, req, resp);

+						

+					switch(r.status) {

+						case OK:

+							resp.setStatus(HttpStatus.CREATED_201); 

+							break;

+						default:

+							context.error(trans,resp,r);

+					}

+				}

+			}

+		);

+		

+		/**

+		 * Get all Roles by Permission

+		 */

+		authzAPI.route(GET,"/authz/roles/perm/:type/:instance/:action",API.ROLES,new Code(facade,"GetRolesByPerm",true) {

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.getRolesByPerm(trans, resp, 

+						pathParam(req, "type"),

+						pathParam(req, "instance"),

+						pathParam(req, "action"));

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Set a role's description

+		 */

+		authzAPI.route(PUT,"/authz/role",API.ROLE_REQ,new Code(facade,"Set Description for role",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.updateRoleDescription(trans, req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});	

+		

+		/**

+		 * Set a permission's roles to roles given

+		 */

+		authzAPI.route(PUT,"/authz/role/perm",API.ROLE_PERM_REQ,new Code(facade,"Set a Permission's Roles",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans, 

+					HttpServletRequest req,

+					HttpServletResponse resp) throws Exception {

+				

+				Result<Void> r = context.resetPermRoles(trans, req, resp);

+				switch(r.status) {

+					case OK: 

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});	

+		

+		/**

+		 * Delete a Permission from a Role

+		 */

+		authzAPI.route(DELETE,"/authz/role/:role/perm",API.ROLE_PERM_REQ, new Code(facade,"Delete Permission from Role",true) {

+			@Override

+			public void handle(

+					AuthzTrans trans,

+					HttpServletRequest req, 

+					HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.delPermFromRole(trans, req, resp);

+					

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		

+		}

+	);

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_User.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_User.java
new file mode 100644
index 0000000..40f5b8a
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_User.java
@@ -0,0 +1,134 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+/**

+ * User Role APIs

+ *

+ */

+public class API_User {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * get all Users who have Permission X

+		 */

+		authzAPI.route(GET,"/authz/users/perm/:type/:instance/:action",API.USERS,new Code(facade,"Get Users By Permission", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+//				trans.checkpoint(pathParam(req,"type") + " " 

+//						+ pathParam(req,"instance") + " " 

+//						+ pathParam(req,"action"));

+//

+				Result<Void> r = context.getUsersByPermission(trans, resp,

+						pathParam(req, ":type"),

+						pathParam(req, ":instance"),

+						pathParam(req, ":action"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+

+		/**

+		 * get all Users who have Role X

+		 */

+		authzAPI.route(GET,"/authz/users/role/:role",API.USERS,new Code(facade,"Get Users By Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getUsersByRole(trans, resp, pathParam(req, ":role"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Get User Role if exists

+		 * @deprecated

+		 */

+		authzAPI.route(GET,"/authz/userRole/:user/:role",API.USERS,new Code(facade,"Get if User is In Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getUserInRole(trans, resp, pathParam(req,":user"),pathParam(req,":role"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		/**

+		 * Get User Role if exists

+		 */

+		authzAPI.route(GET,"/authz/users/:user/:role",API.USERS,new Code(facade,"Get if User is In Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getUserInRole(trans, resp, pathParam(req,":user"),pathParam(req,":role"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+

+

+	}

+		

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_UserRole.java b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_UserRole.java
new file mode 100644
index 0000000..81b16fa
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/api/API_UserRole.java
@@ -0,0 +1,182 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.onap.aaf.authz.layer.Result.OK;

+import static org.onap.aaf.cssa.rserv.HttpMethods.DELETE;

+import static org.onap.aaf.cssa.rserv.HttpMethods.GET;

+import static org.onap.aaf.cssa.rserv.HttpMethods.POST;

+import static org.onap.aaf.cssa.rserv.HttpMethods.PUT;

+

+import javax.servlet.http.HttpServletRequest;

+import javax.servlet.http.HttpServletResponse;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.Code;

+import org.onap.aaf.authz.service.mapper.Mapper.API;

+

+import com.att.aft.dme2.internal.jetty.http.HttpStatus;

+

+/**

+ * User Role APIs

+ *

+ */

+public class API_UserRole {

+	/**

+	 * Normal Init level APIs

+	 * 

+	 * @param authzAPI

+	 * @param facade

+	 * @throws Exception

+	 */

+	public static void init(final AuthAPI authzAPI, AuthzFacade facade) throws Exception {

+		/**

+		 * Request User Role Access

+		 */

+		authzAPI.route(POST,"/authz/userRole",API.USER_ROLE_REQ,new Code(facade,"Request User Role Access", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.requestUserRole(trans, req, resp);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.CREATED_201); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		

+		/**

+		 * Get UserRoles by Role

+		 */

+		authzAPI.route(GET,"/authz/userRoles/role/:role",API.USER_ROLES,new Code(facade,"Get UserRoles by Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getUserRolesByRole(trans, resp, pathParam(req,":role"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Get UserRoles by User

+		 */

+		authzAPI.route(GET,"/authz/userRoles/user/:user",API.USER_ROLES,new Code(facade,"Get UserRoles by User", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.getUserRolesByUser(trans, resp, pathParam(req,":user"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+		

+		/**

+		 * Update roles attached to user in path

+		 */

+		authzAPI.route(PUT,"/authz/userRole/user",API.USER_ROLE_REQ,new Code(facade,"Update Roles for a user", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.resetRolesForUser(trans, resp, req);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		

+		/**

+		 * Update users attached to role in path

+		 */

+		authzAPI.route(PUT,"/authz/userRole/role",API.USER_ROLE_REQ,new Code(facade,"Update Users for a role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.resetUsersForRole(trans, resp, req);

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+		

+		/**

+		 * Extend Expiration Date (according to Organizational rules)

+		 */

+		authzAPI.route(PUT, "/authz/userRole/extend/:user/:role", API.VOID, new Code(facade,"Extend Expiration", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.extendUserRoleExpiration(trans,resp,pathParam(req,":user"),pathParam(req,":role"));

+				switch(r.status) {

+				case OK:

+					resp.setStatus(HttpStatus.OK_200); 

+					break;

+				default:

+					context.error(trans,resp,r);

+			}

+	

+			}

+			

+		});

+		

+		

+		/**

+		 * Create a new ID/Credential

+		 */

+		authzAPI.route(DELETE,"/authz/userRole/:user/:role",API.VOID,new Code(facade,"Delete User Role", true) {

+			@Override

+			public void handle(AuthzTrans trans, HttpServletRequest req, HttpServletResponse resp) throws Exception {

+				Result<Void> r = context.deleteUserRole(trans, resp, pathParam(req,":user"),pathParam(req,":role"));

+				switch(r.status) {

+					case OK:

+						resp.setStatus(HttpStatus.OK_200); 

+						break;

+					default:

+						context.error(trans,resp,r);

+				}

+			}

+		});

+

+	}

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper.java b/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper.java
new file mode 100644
index 0000000..ba3a69e
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper.java
@@ -0,0 +1,123 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.mapper;

+

+import java.util.Collection;

+import java.util.List;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.service.MayChange;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.FutureDAO;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+

+import org.onap.aaf.rosetta.Marshal;

+

+public interface Mapper<

+	NSS,

+	PERMS,

+	PERMKEY,

+	ROLES,

+	USERS,

+	USERROLES,

+	DELGS,

+	CERTS,

+	KEYS,

+	REQUEST,

+	HISTORY,

+	ERROR,

+	APPROVALS>

+{

+	enum API{NSS,NS_REQ,	

+			 PERMS,PERM_KEY,PERM_REQ,

+			 ROLES,ROLE,ROLE_REQ,ROLE_PERM_REQ,

+			 USERS,USER_ROLE_REQ,USER_ROLES,

+			 CRED_REQ,CERTS,

+			 APPROVALS,

+			 DELGS,DELG_REQ,

+			 KEYS,

+			 HISTORY,

+			 ERROR,

+			 API,

+			 VOID};

+	public Class<?> getClass(API api);

+	public<A> Marshal<A> getMarshal(API api);

+	public<A> A newInstance(API api);

+

+	public Result<PermDAO.Data> permkey(AuthzTrans trans, PERMKEY from);

+	public Result<PermDAO.Data> perm(AuthzTrans trans, REQUEST from);

+	public Result<RoleDAO.Data> role(AuthzTrans trans, REQUEST from);

+	public Result<Namespace> ns(AuthzTrans trans, REQUEST from);

+	public Result<CredDAO.Data> cred(AuthzTrans trans, REQUEST from, boolean requiresPass);

+	public Result<USERS> cred(List<CredDAO.Data> lcred, USERS to);

+	public Result<CERTS> cert(List<CertDAO.Data> lcert, CERTS to);

+	public Result<DelegateDAO.Data> delegate(AuthzTrans trans, REQUEST from);

+	public Result<DELGS> delegate(List<DelegateDAO.Data> lDelg);

+	public Result<APPROVALS> approvals(List<ApprovalDAO.Data> lAppr);

+	public Result<List<ApprovalDAO.Data>> approvals(APPROVALS apprs);

+	public Result<List<PermDAO.Data>> perms(AuthzTrans trans, PERMS perms);

+	

+	public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, REQUEST from);

+	public Result<PermDAO.Data> permFromRPRequest(AuthzTrans trans, REQUEST from);

+	public Result<RoleDAO.Data> roleFromRPRequest(AuthzTrans trans, REQUEST from);

+	

+	/*

+	 * Check Requests of varying sorts for Future fields set

+	 */

+	public Result<FutureDAO.Data> future(AuthzTrans trans, String table, REQUEST from, Bytification content, boolean enableApproval, Memo memo, MayChange mc);

+

+	public Result<NSS> nss(AuthzTrans trans, Namespace from, NSS to);

+

+	// Note: Prevalidate if NS given is allowed to be seen before calling

+	public Result<NSS> nss(AuthzTrans trans, Collection<Namespace> from, NSS to);

+//	public Result<NSS> ns_attrib(AuthzTrans trans, Set<String> from, NSS to);

+	public Result<PERMS> perms(AuthzTrans trans, List<PermDAO.Data> from, PERMS to, boolean filter);

+	public Result<ROLES> roles(AuthzTrans trans, List<RoleDAO.Data> from, ROLES roles, boolean filter);

+	// Note: Prevalidate if NS given is allowed to be seen before calling

+	public Result<USERS> users(AuthzTrans trans, Collection<UserRoleDAO.Data> from, USERS to);

+	public Result<USERROLES> userRoles(AuthzTrans trans, Collection<UserRoleDAO.Data> from, USERROLES to);

+	public Result<KEYS> keys(Collection<String> from);

+

+	public Result<HISTORY> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort);

+	

+	public ERROR errorFromMessage(StringBuilder holder, String msgID, String text, String... detail);

+	

+	/*

+	 * A Memo Creator... Use to avoid creating superfluous Strings until needed.

+	 */

+	public static interface Memo {

+		public String get();

+	}

+

+

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper_2_0.java b/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper_2_0.java
new file mode 100644
index 0000000..180e16b
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/mapper/Mapper_2_0.java
@@ -0,0 +1,791 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.mapper;

+

+import java.nio.ByteBuffer;

+import java.util.ArrayList;

+import java.util.Collection;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.Date;

+import java.util.GregorianCalendar;

+import java.util.List;

+import java.util.UUID;

+

+import javax.xml.datatype.XMLGregorianCalendar;

+

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.org.Organization.Expiration;

+import org.onap.aaf.authz.service.MayChange;

+import org.onap.aaf.cssa.rserv.Pair;

+import org.onap.aaf.dao.Bytification;

+import org.onap.aaf.dao.aaf.cass.ApprovalDAO;

+import org.onap.aaf.dao.aaf.cass.CertDAO;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.FutureDAO;

+import org.onap.aaf.dao.aaf.cass.HistoryDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.NsSplit;

+import org.onap.aaf.dao.aaf.cass.NsType;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.Status;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO.Data;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.onap.aaf.dao.aaf.hl.Question.Access;

+

+import org.onap.aaf.cadi.aaf.marshal.CertsMarshal;

+import org.onap.aaf.cadi.util.Vars;

+import org.onap.aaf.inno.env.Env;

+import org.onap.aaf.inno.env.TimeTaken;

+import org.onap.aaf.inno.env.util.Chrono;

+import org.onap.aaf.rosetta.Marshal;

+

+import aaf.v2_0.Api;

+import aaf.v2_0.Approval;

+import aaf.v2_0.Approvals;

+import aaf.v2_0.Certs;

+import aaf.v2_0.Certs.Cert;

+import aaf.v2_0.CredRequest;

+import aaf.v2_0.Delg;

+import aaf.v2_0.DelgRequest;

+import aaf.v2_0.Delgs;

+import aaf.v2_0.Error;

+import aaf.v2_0.History;

+import aaf.v2_0.History.Item;

+import aaf.v2_0.Keys;

+import aaf.v2_0.NsRequest;

+import aaf.v2_0.Nss;

+import aaf.v2_0.Nss.Ns;

+import aaf.v2_0.Nss.Ns.Attrib;

+import aaf.v2_0.Perm;

+import aaf.v2_0.PermKey;

+import aaf.v2_0.PermRequest;

+import aaf.v2_0.Perms;

+import aaf.v2_0.Pkey;

+import aaf.v2_0.Request;

+import aaf.v2_0.Role;

+import aaf.v2_0.RolePermRequest;

+import aaf.v2_0.RoleRequest;

+import aaf.v2_0.Roles;

+import aaf.v2_0.UserRole;

+import aaf.v2_0.UserRoleRequest;

+import aaf.v2_0.UserRoles;

+import aaf.v2_0.Users;

+import aaf.v2_0.Users.User;

+

+public class Mapper_2_0 implements Mapper<Nss, Perms, Pkey, Roles, Users, UserRoles, Delgs, Certs, Keys, Request, History, Error, Approvals> {

+	private Question q;

+

+	public Mapper_2_0(Question q) {

+		this.q = q;

+	}

+	

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.mapper.Mapper#ns(java.lang.Object, org.onap.aaf.authz.service.mapper.Mapper.Holder)

+	 */

+	@Override

+	public Result<Namespace> ns(AuthzTrans trans, Request base) {

+		NsRequest from = (NsRequest)base;

+		Namespace namespace = new Namespace();

+		namespace.name = from.getName();

+		namespace.admin = from.getAdmin();

+		namespace.owner = from.getResponsible();

+		namespace.description = from.getDescription();

+		trans.checkpoint(namespace.name, Env.ALWAYS);

+		

+		NsType nt = NsType.fromString(from.getType());

+		if(nt.equals(NsType.UNKNOWN)) {

+			String ns = namespace.name;

+			int count = 0;

+			for(int i=ns.indexOf('.');

+					i>=0;

+					i=ns.indexOf('.',i+1)) {

+				++count;

+			}

+			switch(count) {

+				case 0: nt = NsType.ROOT;break;

+				case 1: nt = NsType.COMPANY;break;

+				default: nt = NsType.APP;

+			}

+		}

+		namespace.type = nt.type;

+		

+		return Result.ok(namespace);

+	}

+

+	@Override

+	public Result<Nss> nss(AuthzTrans trans, Namespace from, Nss to) {

+		List<Ns> nss = to.getNs();

+		Ns ns = new Ns();

+		ns.setName(from.name);

+		if(from.admin!=null)ns.getAdmin().addAll(from.admin);

+		if(from.owner!=null)ns.getResponsible().addAll(from.owner);

+		if(from.attrib!=null) {

+			for(Pair<String,String> attrib : from.attrib) {

+				Attrib toAttrib = new Attrib();

+				toAttrib.setKey(attrib.x);

+				toAttrib.setValue(attrib.y);

+				ns.getAttrib().add(toAttrib);

+			}

+		}

+

+		ns.setDescription(from.description);

+		nss.add(ns);

+		return Result.ok(to);

+	}

+

+	/**

+	 * Note: Prevalidate if NS given is allowed to be seen before calling

+	 */

+	@Override

+	public Result<Nss> nss(AuthzTrans trans, Collection<Namespace> from, Nss to) {

+		List<Ns> nss = to.getNs();

+		for(Namespace nd : from) {

+			Ns ns = new Ns();

+			ns.setName(nd.name);

+			ns.getAdmin().addAll(nd.admin);

+			ns.getResponsible().addAll(nd.owner);

+			ns.setDescription(nd.description);

+			if(nd.attrib!=null) {

+				for(Pair<String,String> attrib : nd.attrib) {

+					Attrib toAttrib = new Attrib();

+					toAttrib.setKey(attrib.x);

+					toAttrib.setValue(attrib.y);

+					ns.getAttrib().add(toAttrib);

+				}

+			}

+

+			nss.add(ns);

+		}

+		return Result.ok(to);

+	}

+

+	@Override

+	public Result<Perms> perms(AuthzTrans trans, List<PermDAO.Data> from, Perms to, boolean filter) {

+		List<Perm> perms = to.getPerm();

+		TimeTaken tt = trans.start("Filter Perms before return", Env.SUB);

+		try {

+			if(from!=null) {

+				for (PermDAO.Data data : from) {

+					if(!filter || q.mayUser(trans, trans.user(), data, Access.read).isOK()) {

+						Perm perm = new Perm();

+						perm.setType(data.fullType());

+						perm.setInstance(data.instance);

+						perm.setAction(data.action);

+						for(String role : data.roles(false)) {

+							perm.getRoles().add(role);

+						}

+						perm.setDescription(data.description);

+						perms.add(perm);

+					}

+				}

+			}

+		} finally {

+			tt.done();

+		}

+		 

+		tt = trans.start("Sort Perms", Env.SUB);

+		try {

+			Collections.sort(perms, new Comparator<Perm>() {

+				@Override

+				public int compare(Perm perm1, Perm perm2) {

+					int typeCompare = perm1.getType().compareToIgnoreCase(perm2.getType());

+					if (typeCompare == 0) {

+						int instanceCompare = perm1.getInstance().compareToIgnoreCase(perm2.getInstance());

+						if (instanceCompare == 0) {

+							return perm1.getAction().compareToIgnoreCase(perm2.getAction());

+						}

+						return instanceCompare;

+					}

+					return typeCompare;

+				}	

+			});

+		} finally {

+			tt.done();

+		}

+		return Result.ok(to);

+	}

+	

+	@Override

+	public Result<List<PermDAO.Data>> perms(AuthzTrans trans, Perms perms) {

+		List<PermDAO.Data> lpd = new ArrayList<PermDAO.Data>();

+		for (Perm p : perms.getPerm()) {

+			Result<NsSplit> nss = q.deriveNsSplit(trans, p.getType());

+			PermDAO.Data pd = new PermDAO.Data();

+			if(nss.isOK()) { 

+				pd.ns=nss.value.ns;

+				pd.type = nss.value.name;

+				pd.instance = p.getInstance();

+				pd.action = p.getAction();

+				for (String role : p.getRoles())

+					pd.roles(true).add(role);

+				lpd.add(pd);

+			} else {

+				return Result.err(nss);

+			}

+		}

+		return Result.ok(lpd);

+	}

+

+	@Override

+	public Result<PermDAO.Data> permkey(AuthzTrans trans, Pkey from) {

+		return q.permFrom(trans, from.getType(),from.getInstance(),from.getAction());

+	}

+	

+	@Override

+	public Result<PermDAO.Data> permFromRPRequest(AuthzTrans trans, Request req) {

+		RolePermRequest from = (RolePermRequest)req;

+		Pkey perm = from.getPerm();

+		if(perm==null)return Result.err(Status.ERR_NotFound, "Permission not found");

+		Result<NsSplit> nss = q.deriveNsSplit(trans, perm.getType());

+		PermDAO.Data pd = new PermDAO.Data();

+		if(nss.isOK()) { 

+			pd.ns=nss.value.ns;

+			pd.type = nss.value.name;

+			pd.instance = from.getPerm().getInstance();

+			pd.action = from.getPerm().getAction();

+			trans.checkpoint(pd.fullPerm(), Env.ALWAYS);

+			

+			String[] roles = {};

+			

+			if (from.getRole() != null) {

+				roles = from.getRole().split(",");

+			}

+			for (String role : roles) { 

+				pd.roles(true).add(role);

+			}

+			return Result.ok(pd);

+		} else {

+			return Result.err(nss);

+		}

+	}

+	

+	@Override

+	public Result<RoleDAO.Data> roleFromRPRequest(AuthzTrans trans, Request req) {

+		RolePermRequest from = (RolePermRequest)req;

+		Result<NsSplit> nss = q.deriveNsSplit(trans, from.getRole());

+		RoleDAO.Data rd = new RoleDAO.Data();

+		if(nss.isOK()) { 

+			rd.ns = nss.value.ns;

+			rd.name = nss.value.name;

+			trans.checkpoint(rd.fullName(), Env.ALWAYS);

+			return Result.ok(rd);

+		} else {

+			return Result.err(nss);

+		}

+	}

+	

+	@Override

+	public Result<PermDAO.Data> perm(AuthzTrans trans, Request req) {

+		PermRequest from = (PermRequest)req;

+		Result<NsSplit> nss = q.deriveNsSplit(trans, from.getType());

+		PermDAO.Data pd = new PermDAO.Data();

+		if(nss.isOK()) { 

+			pd.ns=nss.value.ns;

+			pd.type = nss.value.name;

+			pd.instance = from.getInstance();

+			pd.action = from.getAction();

+			pd.description = from.getDescription();

+			trans.checkpoint(pd.fullPerm(), Env.ALWAYS);

+			return Result.ok(pd);

+		} else {

+			return Result.err(nss);

+		}

+	}

+

+	@Override

+	public Result<RoleDAO.Data> role(AuthzTrans trans, Request base) {

+		RoleRequest from = (RoleRequest)base;

+		Result<NsSplit> nss = q.deriveNsSplit(trans, from.getName());

+		if(nss.isOK()) {

+			RoleDAO.Data to = new RoleDAO.Data();

+			to.ns = nss.value.ns;

+			to.name = nss.value.name;

+			to.description = from.getDescription();

+			trans.checkpoint(to.fullName(), Env.ALWAYS);

+

+			return Result.ok(to);

+		} else {

+			return Result.err(nss);

+		}

+	}

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.mapper.Mapper#roles(java.util.List)

+	 */

+	@Override

+	public Result<Roles> roles(AuthzTrans trans, List<RoleDAO.Data> from, Roles to, boolean filter) {

+		for(RoleDAO.Data frole : from) {

+			// Only Add Data to view if User is allowed to see this Role 

+			//if(!filter || q.mayUserViewRole(trans, trans.user(), frole).isOK()) {

+			if(!filter || q.mayUser(trans, trans.user(), frole,Access.read).isOK()) {

+				Role role = new Role();

+				role.setName(frole.ns + '.' + frole.name);

+				role.setDescription(frole.description);

+				for(String p : frole.perms(false)) { // can see any Perms in the Role he has permission for

+					Result<String[]> rpa = PermDAO.Data.decodeToArray(trans,q,p);

+					if(rpa.notOK()) return Result.err(rpa);

+					

+					String[] pa = rpa.value;

+					Pkey pKey = new Pkey();

+					pKey.setType(pa[0]+'.'+pa[1]);

+					pKey.setInstance(pa[2]);

+					pKey.setAction(pa[3]);

+					role.getPerms().add(pKey);

+				}

+				to.getRole().add(role);

+			}

+		}

+		return Result.ok(to);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)

+	 * 

+	 * Note: Prevalidate all data for permission to view

+	 */

+	@Override

+	public Result<Users> users(AuthzTrans trans, Collection<UserRoleDAO.Data> from, Users to) {

+		List<User> cu = to.getUser();

+		for(UserRoleDAO.Data urd : from) {

+			User user = new User();

+			user.setId(urd.user);

+			user.setExpires(Chrono.timeStamp(urd.expires));

+			cu.add(user);

+		}

+		return Result.ok(to);

+	}

+

+	/*

+	 * (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.mapper.Mapper#users(java.util.Collection, java.lang.Object)

+	 * 

+	 * Note: Prevalidate all data for permission to view

+	 */

+	@Override

+	public Result<UserRoles> userRoles(AuthzTrans trans, Collection<UserRoleDAO.Data> from, UserRoles to) {

+		List<UserRole> cu = to.getUserRole();

+		for(UserRoleDAO.Data urd : from) {

+			UserRole ur = new UserRole();

+			ur.setUser(urd.user);

+			ur.setRole(urd.role);

+			ur.setExpires(Chrono.timeStamp(urd.expires));

+			cu.add(ur);

+		}

+		return Result.ok(to);

+	}

+

+	/**

+	 * 

+	 * @param base

+	 * @param start

+	 * @return

+	 */

+	@Override

+	public Result<UserRoleDAO.Data> userRole(AuthzTrans trans, Request base) {

+		try {

+			UserRoleRequest from = (UserRoleRequest)base;

+

+			// Setup UserRoleData, either for immediate placement, or for future

+			UserRoleDAO.Data to = new UserRoleDAO.Data();

+			if (from.getUser() != null) {

+				String user = from.getUser();

+				to.user = user;

+			}

+			if (from.getRole() != null) {

+				to.role(trans,q,from.getRole());

+			}

+			to.expires = getExpires(trans.org(),Expiration.UserInRole,base,from.getUser());

+			trans.checkpoint(to.toString(), Env.ALWAYS);

+

+			return Result.ok(to);

+		} catch (Exception t) {

+			return Result.err(Status.ERR_BadData,t.getMessage());

+		}

+	}

+

+	@Override

+	public Result<CredDAO.Data> cred(AuthzTrans trans, Request base, boolean requiresPass) {

+		CredRequest from = (CredRequest)base;

+		CredDAO.Data to = new CredDAO.Data();

+		to.id=from.getId();

+		to.ns = Question.domain2ns(to.id);

+		String passwd = from.getPassword();

+		if(requiresPass) {

+			String ok = trans.org().isValidPassword(to.id,passwd);

+			if(ok.length()>0) {

+				return Result.err(Status.ERR_BadData,ok);

+			}

+

+		} else {

+			to.type=0;

+		}

+		if(passwd != null) {

+			to.cred = ByteBuffer.wrap(passwd.getBytes());

+			to.type = CredDAO.RAW; 

+		} else {

+			to.type = 0;

+		}

+		

+		// Note: Ensure requested EndDate created will match Organization Password Rules

+		//  P.S. Do not apply TempPassword rule here. Do that when you know you are doing a Create/Reset (see Service)

+		to.expires = getExpires(trans.org(),Expiration.Password,base,from.getId());

+		trans.checkpoint(to.id, Env.ALWAYS);

+

+		return Result.ok(to);

+	}

+	

+	@Override

+	public Result<Users> cred(List<CredDAO.Data> from, Users to) {

+		List<User> cu = to.getUser();

+		for(CredDAO.Data cred : from) {

+			User user = new User();

+			user.setId(cred.id);

+			user.setExpires(Chrono.timeStamp(cred.expires));

+			user.setType(cred.type);

+			cu.add(user);

+		}

+		return Result.ok(to);

+	}

+	

+@Override

+	public Result<Certs> cert(List<CertDAO.Data> from, Certs to) {

+		List<Cert> lc = to.getCert();

+		for(CertDAO.Data fcred : from) {

+			Cert cert = new Cert();

+			cert.setId(fcred.id);

+			cert.setX500(fcred.x500);

+			/**TODO - change Interface 

+			 * @deprecated */

+			cert.setFingerprint(fcred.serial.toByteArray());

+			lc.add(cert);

+		}

+		return Result.ok(to);

+	}

+

+	/**

+	 * Analyze whether Requests should be acted on now, or in the future, based on Start Date, and whether the requester

+	 * is allowed to change this value directly

+	 * 

+	 * Returning Result.OK means it should be done in the future.

+	 * Returning Result.ACC_Now means to act on table change now.

+	 */

+	@Override

+	public Result<FutureDAO.Data> future(AuthzTrans trans, String table, Request from, 

+				Bytification content, boolean enableApproval,  Memo memo, MayChange mc) {

+		Result<?> rMayChange = mc.mayChange();

+		boolean needsAppr;

+		if(needsAppr = rMayChange.notOK()) {

+			if(enableApproval) {

+				if(!trans.futureRequested()) {

+					return Result.err(rMayChange);

+				}

+			} else {

+				return Result.err(rMayChange);

+			}

+		}

+		GregorianCalendar now = new GregorianCalendar(); 

+		GregorianCalendar start = from.getStart()==null?now:from.getStart().toGregorianCalendar();

+		

+		GregorianCalendar expires = trans.org().expiration(start, Expiration.Future);

+		XMLGregorianCalendar xgc;

+		if((xgc=from.getEnd())!=null) {

+			GregorianCalendar fgc = xgc.toGregorianCalendar();

+			expires = expires.before(fgc)?expires:fgc; // Min of desired expiration, and Org expiration

+		}

+		

+		//TODO needs two answers from this.  What's the NSS, and may Change.

+		FutureDAO.Data fto;

+		if(start.after(now) || needsAppr ) {

+			//String user = trans.user();

+			fto = new FutureDAO.Data();

+			fto.target=table;

+			fto.memo = memo.get();

+			fto.start = start.getTime();

+			fto.expires = expires.getTime();

+			if(needsAppr) { // Need to add Approvers...

+				/*

+				Result<Data> rslt = mc.getNsd();

+				if(rslt.notOKorIsEmpty())return Result.err(rslt);

+				appr.addAll(mc.getNsd().value.responsible);

+				try {

+					//Note from 2013 Is this getting Approvers for user only?  What about Delegates?

+					// 3/25/2014.  Approvers are set by Corporate policy.  We don't have to worry here about what that means.

+					// It is important to get Delegates, if necessary, at notification time

+					// If we add delegates now, it will get all confused as to who is actually responsible.

+					for(Organization.User ou : org.getApprovers(trans, user)) {

+						appr.add(ou.email);

+					}

+				} catch (Exception e) {

+					return Result.err(Status.ERR_Policy,org.getName() + " did not respond with Approvers: " + e.getLocalizedMessage());

+				}

+				*/

+			}

+			try {

+				fto.construct = content.bytify();

+			} catch (Exception e) {

+				return Result.err(Status.ERR_BadData,"Data cannot be saved for Future.");

+			}

+		} else {

+			return Result.err(Status.ACC_Now, "Make Data changes now.");

+		}

+		return Result.ok(fto);

+	}

+

+

+	/* (non-Javadoc)

+	 * @see org.onap.aaf.authz.service.mapper.Mapper#history(java.util.List)

+	 */

+	@Override

+	public Result<History> history(AuthzTrans trans, List<HistoryDAO.Data> history, final int sort) {

+		History hist = new History();

+		List<Item> items = hist.getItem();

+		for(HistoryDAO.Data data : history) {

+			History.Item item = new History.Item();

+			item.setYYYYMM(Integer.toString(data.yr_mon));

+			Date date = Chrono.uuidToDate(data.id);

+			item.setTimestamp(Chrono.timeStamp(date));

+			item.setAction(data.action);

+			item.setMemo(data.memo);

+			item.setSubject(data.subject);

+			item.setTarget(data.target);

+			item.setUser(data.user);

+			items.add(item);

+		}

+		

+		if(sort != 0) {

+			TimeTaken tt = trans.start("Sort ", Env.SUB);

+			try {

+				java.util.Collections.sort(items, new Comparator<Item>() {

+					@Override

+					public int compare(Item o1, Item o2) {

+						return sort*(o1.getTimestamp().compare(o2.getTimestamp()));

+					}

+				});

+			} finally {

+				tt.done();

+			}

+		}

+		return Result.ok(hist);

+	}

+

+	@Override

+	public Error errorFromMessage(StringBuilder holder, String msgID, String text, String... var) {

+		Error err = new Error();

+		err.setMessageId(msgID);

+		// AT&T Restful Error Format requires numbers "%" placements

+		err.setText(Vars.convert(holder, text, var));

+		for(String s : var) {

+			err.getVariables().add(s);

+		}

+		return err;

+	}

+	

+	@Override

+	public Class<?> getClass(API api) {

+		switch(api) {

+			case NSS:  return Nss.class;

+			case NS_REQ: return NsRequest.class;

+			case PERMS: return Perms.class;

+			case PERM_KEY: return PermKey.class;

+			case ROLES: return Roles.class;

+			case ROLE: return Role.class;

+			case USERS: return Users.class;

+			case DELGS: return Delgs.class;

+			case CERTS: return Certs.class;

+			case DELG_REQ: return DelgRequest.class;

+			case PERM_REQ: return PermRequest.class;

+			case ROLE_REQ:  return RoleRequest.class;

+			case CRED_REQ:  return CredRequest.class;

+			case USER_ROLE_REQ:  return UserRoleRequest.class;

+			case USER_ROLES: return UserRoles.class;

+			case ROLE_PERM_REQ:  return RolePermRequest.class;

+			case APPROVALS: return Approvals.class;

+			case KEYS: return Keys.class;

+			case HISTORY: return History.class;

+//			case MODEL: return Model.class;

+			case ERROR: return Error.class;

+			case API: return Api.class;

+			case VOID: return Void.class;

+		}

+		return null;

+	}

+

+	@SuppressWarnings("unchecked")

+	@Override

+	public <A> A newInstance(API api) {

+		switch(api) {

+			case NS_REQ: return (A) new NsRequest();

+			case NSS: return (A) new Nss();

+			case PERMS: return (A)new Perms();

+			case PERM_KEY: return (A)new PermKey();

+			case ROLES: return (A)new Roles();

+			case ROLE: return (A)new Role();

+			case USERS: return (A)new Users();

+			case DELGS: return (A)new Delgs();

+			case CERTS: return (A)new Certs();

+			case PERM_REQ: return (A)new PermRequest();

+			case CRED_REQ: return (A)new CredRequest();

+			case ROLE_REQ:  return (A)new RoleRequest();

+			case USER_ROLE_REQ:  return (A)new UserRoleRequest();

+			case USER_ROLES:  return (A)new UserRoles();

+			case ROLE_PERM_REQ:  return (A)new RolePermRequest();

+			case HISTORY: return (A)new History();

+			case KEYS: return (A)new Keys();

+			//case MODEL: return (A)new Model();

+			case ERROR: return (A)new Error();

+			case API: return (A)new Api();

+			case VOID: return null;

+			

+			case APPROVALS:	return (A) new Approvals();

+			case DELG_REQ: return (A) new DelgRequest();

+		}

+		return null;

+	}

+	

+	@SuppressWarnings("unchecked")

+	/**

+	 * Get Typed Marshaler as they are defined

+	 * 

+	 * @param api

+	 * @return

+	 */

+	public <A> Marshal<A> getMarshal(API api) {

+		switch(api) {

+			case CERTS: return (Marshal<A>) new CertsMarshal();

+			default:

+				return null;

+		}

+	}

+

+	@Override

+	public Result<Approvals> approvals(List<ApprovalDAO.Data> lAppr) {

+		Approvals apprs = new Approvals();

+		List<Approval> lappr = apprs.getApprovals();

+		Approval a;

+		for(ApprovalDAO.Data appr : lAppr) {

+			a = new Approval();

+			a.setId(appr.id.toString());

+			a.setTicket(appr.ticket.toString());

+			a.setUser(appr.user);

+			a.setApprover(appr.approver);

+			a.setType(appr.type);

+			a.setStatus(appr.status);

+			a.setMemo(appr.memo);

+			a.setOperation(appr.operation);

+			a.setUpdated(Chrono.timeStamp(appr.updated));

+			lappr.add(a);

+		}

+		return Result.ok(apprs);

+	}

+	

+	@Override

+	public Result<List<ApprovalDAO.Data>> approvals(Approvals apprs) {

+		List<ApprovalDAO.Data>  lappr = new ArrayList<ApprovalDAO.Data>();

+		for(Approval a : apprs.getApprovals()) {

+			ApprovalDAO.Data ad = new ApprovalDAO.Data();

+			String str = a.getId();

+			if(str!=null)ad.id=UUID.fromString(str);

+			str = a.getTicket();

+			if(str!=null)ad.ticket=UUID.fromString(str);

+			ad.user=a.getUser();

+			ad.approver=a.getApprover();

+			ad.type=a.getType();

+			ad.status=a.getStatus();

+			ad.operation=a.getOperation();

+			ad.memo=a.getMemo();

+			

+			XMLGregorianCalendar xgc = a.getUpdated();

+			if(xgc!=null)ad.updated=xgc.toGregorianCalendar().getTime();

+			lappr.add(ad);

+		}

+		return Result.ok(lappr);

+	}

+

+	@Override

+	public Result<Delgs> delegate(List<DelegateDAO.Data> lDelg) {

+		Delgs delgs = new Delgs();

+		List<Delg> ldelg = delgs.getDelgs();

+		Delg d;

+		for(DelegateDAO.Data del: lDelg) {

+			d = new Delg();

+			d.setUser(del.user);

+			d.setDelegate(del.delegate);

+			if(del.expires!=null)d.setExpires(Chrono.timeStamp(del.expires));

+			ldelg.add(d);

+		}

+		return Result.ok(delgs);

+	}

+

+	@Override

+	public Result<Data> delegate(AuthzTrans trans, Request base) {

+		try {

+			DelgRequest from = (DelgRequest)base;

+			DelegateDAO.Data to = new DelegateDAO.Data();

+			String user = from.getUser();

+			to.user = user;

+			String delegate = from.getDelegate();

+			to.delegate = delegate;

+			to.expires = getExpires(trans.org(),Expiration.UserDelegate,base,from.getUser());

+			trans.checkpoint(to.user+"=>"+to.delegate, Env.ALWAYS);

+

+			return Result.ok(to);

+		} catch (Exception t) {

+			return Result.err(Status.ERR_BadData,t.getMessage());

+		}

+	}

+

+	/*

+	 * We want "Expired" dates to start at a specified time set by the Organization, and consistent wherever

+	 * the date is created from.

+	 */ 

+	private Date getExpires(Organization org, Expiration exp, Request base, String id) {

+		XMLGregorianCalendar end = base.getEnd();

+		GregorianCalendar gc = end==null?new GregorianCalendar():end.toGregorianCalendar();

+		GregorianCalendar orggc;

+		orggc = org.expiration(gc,exp,id); 

+

+		// We'll choose the lesser of dates to ensure Policy Compliance...

+	

+		GregorianCalendar endgc = end==null||gc.after(orggc)?orggc:gc;

+		// Allow the Organization to determine when official "day Start" begins, Specifically when to consider something Expired.

+		endgc = Chrono.firstMomentOfDay(endgc);

+		endgc.set(GregorianCalendar.HOUR_OF_DAY, org.startOfDay());

+		return endgc.getTime();

+	}

+

+

+	@Override

+	public Result<Keys> keys(Collection<String> from) {

+		Keys keys = new Keys();

+		keys.getKey().addAll(from);

+		return Result.ok(keys).emptyList(from.isEmpty());

+	}

+

+}

diff --git a/authz-service/src/main/java/org/onap/aaf/authz/service/validation/Validator.java b/authz-service/src/main/java/org/onap/aaf/authz/service/validation/Validator.java
new file mode 100644
index 0000000..6eca6ce
--- /dev/null
+++ b/authz-service/src/main/java/org/onap/aaf/authz/service/validation/Validator.java
@@ -0,0 +1,386 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.validation;

+

+import java.util.regex.Pattern;

+

+import org.onap.aaf.authz.cadi.DirectAAFLur.PermPermission;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+

+/**

+ * Validator

+ * Consistently apply content rules for content (incoming)

+ * 

+ * Note: We restrict content for usability in URLs (because RESTful service), and avoid 

+ * issues with Regular Expressions, and other enabling technologies. 

+ *

+ */

+public class Validator {

+	// % () ,-. 0-9 =A-Z _a-z

+	private static final String ESSENTIAL="\\x25\\x28\\x29\\x2C-\\x2E\\x30-\\x39\\x3D\\x40-\\x5A\\x5F\\x61-\\x7A";

+	private static final Pattern ESSENTIAL_CHARS=Pattern.compile("["+ESSENTIAL+"]+");

+	

+	// Must be 1 or more of Alphanumeric or the following  :._-

+	// '*' only allowed when it is the only character, or the only element in a key separator

+	//  :* :hello:* :hello:*:there  etc

+	public static final Pattern ACTION_CHARS=Pattern.compile(

+			"["+ESSENTIAL+"]+" +	// All AlphaNumeric+

+			"|\\*"						// Just Star

+			);

+

+	public static final Pattern INST_CHARS=Pattern.compile(

+			"["+ESSENTIAL+"]+[\\*]*" +				// All AlphaNumeric+ possibly ending with *

+			"|\\*" +								// Just Star

+			"|(([:/]\\*)|([:/][!]{0,1}["+ESSENTIAL+"]+[\\*]*[:/]*))+"	// Key :asdf:*:sdf*:sdk

+			);

+	

+	// Must be 1 or more of Alphanumeric or the following  ._-, and be in the form id@domain

+	public static final Pattern ID_CHARS=Pattern.compile("[\\w.-]+@[\\w.-]+");

+	// Must be 1 or more of Alphanumeric or the following  ._-

+	public static final Pattern NAME_CHARS=Pattern.compile("[\\w.-]+");

+	

+	private final Pattern actionChars;

+	private final Pattern instChars;

+	private StringBuilder msgs;

+

+	/**

+	 * Default Validator does not check for non-standard Action/Inst chars

+	 * 

+	 * 

+	 * IMPORTANT: Use ONLY when the Validator is doing something simple... NullOrBlank

+	 */

+	public Validator() {

+		actionChars = ACTION_CHARS;

+		instChars = INST_CHARS;

+	}

+	

+	/**

+	 * When Trans is passed in, check for non-standard Action/Inst chars

+	 * 

+	 * This is an opportunity to change characters, if required.

+	 * 

+	 * Use for any Object method passed (i.e. role(RoleDAO.Data d) ), to ensure fewer bugs.

+	 * 

+	 * @param trans

+	 */

+	public Validator(AuthzTrans trans) {

+		actionChars = ACTION_CHARS;

+		instChars = INST_CHARS;

+	}

+

+

+	public Validator perm(Result<PermDAO.Data> rpd) {

+		if(rpd.notOK()) {

+			msg(rpd.details);

+		} else {

+			perm(rpd.value);

+		}

+		return this;

+	}

+

+

+	public Validator perm(PermDAO.Data pd) {

+		if(pd==null) {

+			msg("Perm Data is null.");

+		} else {

+			ns(pd.ns);

+			permType(pd.type,pd.ns);

+			permInstance(pd.instance);

+			permAction(pd.action);

+			if(pd.roles!=null) { 

+				for(String role : pd.roles) {

+					role(role);

+				}

+			}

+		}

+		return this;

+	}

+

+	public Validator role(Result<RoleDAO.Data> rrd) {

+		if(rrd.notOK()) {

+			msg(rrd.details);

+		} else {

+			role(rrd.value);

+		}

+		return this;

+	}

+

+	public Validator role(RoleDAO.Data pd) {

+		if(pd==null) {

+			msg("Role Data is null.");

+		} else {

+			ns(pd.ns);

+			role(pd.name);

+			if(pd.perms!=null) {

+				for(String perm : pd.perms) {

+					String[] ps = perm.split("\\|");

+					if(ps.length!=3) {

+						msg("Perm [" + perm + "] in Role [" + pd.fullName() + "] is not correctly separated with '|'");

+					} else {

+						permType(ps[0],null);

+						permInstance(ps[1]);

+						permAction(ps[2]);

+					}

+				}

+			}

+		}

+		return this;

+	}

+

+	public Validator delegate(Organization org, Result<DelegateDAO.Data> rdd) {

+		if(rdd.notOK()) {

+			msg(rdd.details);

+		} else {

+			delegate(org, rdd.value);

+		}

+		return this;

+	}

+

+	public Validator delegate(Organization org, DelegateDAO.Data dd) {

+		if(dd==null) {

+			msg("Delegate Data is null.");

+		} else {

+			user(org,dd.user);

+			user(org,dd.delegate);

+		}

+		return this;

+	}

+

+

+	public Validator cred(Organization org, Result<CredDAO.Data> rcd, boolean isNew) {

+		if(rcd.notOK()) {

+			msg(rcd.details);

+		} else {

+			cred(org,rcd.value,isNew);

+		}

+		return this;

+	}

+

+	public Validator cred(Organization org, CredDAO.Data cd, boolean isNew) {

+		if(cd==null) {

+			msg("Cred Data is null.");

+		} else {

+			if(nob(cd.id,ID_CHARS)) {

+				msg("ID [" + cd.id + "] is invalid");

+			}

+			if(!org.isValidCred(cd.id)) {

+				msg("ID [" + cd.id + "] is invalid for a cred");

+			}

+			String str = cd.id;

+			int idx = str.indexOf('@');

+			if(idx>0) {

+				str = str.substring(0,idx);

+			}

+			

+			if(cd.id.endsWith(org.getRealm())) {

+				if(isNew && (str=org.isValidID(str)).length()>0) {

+					msg(cd.id,str);

+				}

+			}

+	

+			if(cd.type==null) {

+				msg("Credential Type must be set");

+			} else {

+				switch(cd.type) {

+					case CredDAO.BASIC_AUTH_SHA256:

+						// ok

+						break;

+					default:

+						msg("Credential Type [",Integer.toString(cd.type),"] is invalid");

+				}

+			}

+		}

+		return this;

+	}

+

+

+	public Validator user(Organization org, String user) {

+		if(nob(user,ID_CHARS)) {

+			msg("User [",user,"] is invalid.");

+		}

+		//TODO Change when Multi-Org solution is created

+//		if(org instanceof ATT) {

+//			if(!user.endsWith("@csp.att.com") &&

+//			   !org.isValidCred(user)) 

+//					msg("User [",user,"] is not valid ID for Credential in ",org.getRealm());

+//		}

+		return this;

+	}

+

+	public Validator ns(Result<Namespace> nsd) {

+		notOK(nsd);

+		ns(nsd.value.name);

+		for(String s : nsd.value.admin) {

+			if(nob(s,ID_CHARS)) {

+				msg("Admin [" + s + "] is invalid.");		

+			}

+			

+		}

+		for(String s : nsd.value.owner) {

+			if(nob(s,ID_CHARS)) {

+				msg("Responsible [" + s + "] is invalid.");		

+			}

+			

+		}

+		return this;

+	}

+

+

+	public Validator ns(String ns) {

+		if(nob(ns,NAME_CHARS)){

+			msg("NS [" + ns + "] is invalid.");

+		}

+		return this;

+	}

+

+	public String errs() {

+		return msgs.toString();

+	}

+

+

+	public Validator permType(String type, String ns) {

+		// TODO check for correct Splits?  Type|Instance|Action ?

+		if(nob(type,NAME_CHARS)) {

+			msg("Perm Type [" + (ns==null?"":ns+(type.length()==0?"":'.'))+type + "] is invalid.");

+		}

+		return this;

+	}

+

+	public Validator permInstance(String instance) {

+		// TODO check for correct Splits?  Type|Instance|Action ?

+		if(nob(instance,instChars)) {

+			msg("Perm Instance [" + instance + "] is invalid.");

+		}

+		return this;

+	}

+

+	public Validator permAction(String action) {

+		// TODO check for correct Splits?  Type|Instance|Action ?

+		if(nob(action, actionChars)) {

+			msg("Perm Action [" + action + "] is invalid.");

+		}

+		return this;

+	}

+

+	public Validator role(String role) {

+		if(nob(role, NAME_CHARS)) {

+			msg("Role [" + role + "] is invalid.");

+		}

+		return this;

+	}

+

+	public Validator user_role(UserRoleDAO.Data urdd) {

+		if(urdd==null) {

+			msg("UserRole is null");

+		} else {

+			role(urdd.role);

+			nullOrBlank("UserRole.ns",urdd.ns);

+			nullOrBlank("UserRole.rname",urdd.rname);

+		}

+		return this;

+	}

+

+	public Validator nullOrBlank(String name, String str) {

+		if(str==null) {

+			msg(name + " is null.");

+		} else if(str.length()==0) {

+			msg(name + " is blank.");

+		}

+		return this;

+	}

+	

+	public Validator nullOrBlank(PermDAO.Data pd) {

+		if(pd==null) {

+			msg("Permission is null");

+		} else {

+			nullOrBlank("NS",pd.ns).

+			nullOrBlank("Type",pd.type).

+			nullOrBlank("Instance",pd.instance).

+			nullOrBlank("Action",pd.action);

+		}

+		return this;

+	}

+

+	public Validator nullOrBlank(RoleDAO.Data rd) {

+		if(rd==null) {

+			msg("Role is null");

+		} else {

+			nullOrBlank("NS",rd.ns).

+			nullOrBlank("Name",rd.name);

+		}

+		return this;

+	}

+

+	// nob = Null Or Not match Pattern

+	private boolean nob(String str, Pattern p) {

+		return str==null || !p.matcher(str).matches(); 

+	}

+

+	private void msg(String ... strs) {

+		if(msgs==null) {

+			msgs=new StringBuilder();

+		}

+		for(String str : strs) {

+			msgs.append(str);

+		}

+		msgs.append('\n');

+	}

+	

+	public boolean err() {

+		return msgs!=null;

+	}

+

+

+	public Validator notOK(Result<?> res) {

+		if(res==null) {

+			msgs.append("Result object is blank");

+		} else if(res.notOK()) {

+			msgs.append(res.getClass().getSimpleName() + " is not OK");

+		}

+		return this;

+	}

+

+	public Validator key(String key) {

+		if(nob(key,NAME_CHARS)) {

+			msg("NS Prop Key [" + key + "] is invalid");

+		}

+		return this;

+	}

+	

+	public Validator value(String value) {

+		if(nob(value,ESSENTIAL_CHARS)) {

+			msg("NS Prop value [" + value + "] is invalid");

+		}

+		return this;

+	}

+

+

+}

diff --git a/authz-service/src/main/resources/authAPI.props b/authz-service/src/main/resources/authAPI.props
new file mode 100644
index 0000000..6bc7869
--- /dev/null
+++ b/authz-service/src/main/resources/authAPI.props
@@ -0,0 +1,24 @@
+##
+## AUTHZ API (authz-service) Properties
+##
+
+hostname=_HOSTNAME_
+
+## DISCOVERY (DME2) Parameters on the Command Line
+AFT_LATITUDE=_AFT_LATITUDE_
+AFT_LONGITUDE=_AFT_LONGITUDE_
+AFT_ENVIRONMENT=_AFT_ENVIRONMENT_
+DEPLOYED_VERSION=_ARTIFACT_VERSION_
+
+## Pull in common/security properties
+
+cadi_prop_files=_COMMON_DIR_/com.att.aaf.common.props;_COMMON_DIR_/com.att.aaf.props
+
+##DME2 related parameters
+
+DMEServiceName=service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_._PATCH_VER_/envContext=_ENV_CONTEXT_/routeOffer=_ROUTE_OFFER_
+AFT_DME2_PORT_RANGE=_AUTHZ_SERVICE_PORT_RANGE_
+
+
+CACHE_HIGH_COUNT=20000
+CACHE_CLEAN_INTERVAL=60000
\ No newline at end of file
diff --git a/authz-service/src/main/resources/docker-compose/aafcli.sh b/authz-service/src/main/resources/docker-compose/aafcli.sh
new file mode 100644
index 0000000..89e9a4e
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/aafcli.sh
@@ -0,0 +1,9 @@
+DIR=`pwd`
+DME2REG=$DIR/../dme2reg
+CLASSPATH=etc:target/authz-cmd-2.0.15-jar-with-dependencies.jar
+
+java -cp $CLASSPATH \
+	-Dcadi_prop_files=../authz-service/src/main/sample/authAPI.props \
+	-DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG \
+	com.att.cmd.AAFcli $*
+
diff --git a/authz-service/src/main/resources/docker-compose/data/ecomp.cql b/authz-service/src/main/resources/docker-compose/data/ecomp.cql
new file mode 100644
index 0000000..6fddf65
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/data/ecomp.cql
@@ -0,0 +1,169 @@
+USE authz;
+
+// Create Root pass
+INSERT INTO cred (id,ns,type,cred,expires)
+  VALUES ('dgl@openecomp.org','org.openecomp',1,0xab3831f27b39d7a039f9a92aa2bbfe51,'2020-12-31');
+
+INSERT INTO cred (id,ns,type,cred,expires)
+  VALUES ('m99751@dmaapBC.openecomp.org','org.openecomp.dmaapBC',1,0xab3831f27b39d7a039f9a92aa2bbfe51,'2020-12-31');
+
+INSERT INTO cred (id,ns,type,cred,expires)
+  VALUES ('m99501@dmaapBC.openecomp.org','org.openecomp.dmaapBC',1,0xab3831f27b39d7a039f9a92aa2bbfe51,'2020-12-31');
+
+
+// Create 'com' root NS
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com',1,'Root Namespace',null,1);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com','admin',{'com.access|*|*'},'Com Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com','owner',{'com.access|*|read'},'Com Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com','access','*','read',{'com.owner'},'Com Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com','access','*','*',{'com.admin'},'Com Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.owner','2020-12-31','com','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.admin','2020-12-31','com','admin');
+
+// Create org root NS
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org',1,'Root Namespace Org',null,1);
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org.openecomp.dcae',3,'DCAE Namespace Org','org.openecomp',3);
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org.openecomp.dmaapBC',3,'DMaaP BC Namespace Org','org.openecomp',3);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org','admin',{'org.access|*|*'},'Com Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org','owner',{'org.access|*|read'},'Com Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org','access','*','read',{'org.owner'},'Com Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org','access','*','*',{'org.admin'},'Com Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.owner','2020-12-31','org','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.admin','2020-12-31','org','admin');
+
+
+// Create com.att
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com.att',2,'AT&T Namespace','com',2);
+
+INSERT INTO role(ns, name, perms,description)
+  VALUES('com.att','admin',{'com.att.access|*|*'},'AT&T Admins');
+
+INSERT INTO role(ns, name, perms,description)
+  VALUES('com.att','owner',{'com.att.access|*|read'},'AT&T Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles,description) 
+  VALUES ('com.att','access','*','read',{'com.att.owner'},'AT&T Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles,description) 
+  VALUES ('com.att','access','*','*',{'com.att.admin'},'AT&T Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.owner','2020-12-31','com.att','owner');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.admin','2020-12-31','com.att','admin');
+
+// Create com.att.aaf
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('com.att.aaf',3,'Application Authorization Framework','com.att',3);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com.att.aaf','admin',{'com.att.aaf.access|*|*'},'AAF Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('com.att.aaf','owner',{'com.att.aaf.access|*|read'},'AAF Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com.att.aaf','access','*','read',{'com.att.aaf.owner'},'AAF Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('com.att.aaf','access','*','*',{'com.att.aaf.admin'},'AAF Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.aaf.admin','2020-12-31','com.att.aaf','admin');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','com.att.aaf.owner','2020-12-31','com.att.aaf','owner');
+  
+
+// Create org.openecomp
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org.openecomp',2,'Open EComp NS','com.att',2);
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org.openecomp','admin',{'org.openecomp.access|*|*'},'OpenEcomp Admins');
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org.openecomp','owner',{'org.openecomp.access|*|read'},'OpenEcomp Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp','access','*','read',{'org.openecomp.owner'},'OpenEcomp Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp','access','*','*',{'org.openecomp.admin'},'OpenEcomp Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.openecomp.admin','2020-12-31','org.openecomp','admin');
+
+// Create org.openecomp.dmaapBC
+
+INSERT INTO ns (name,scope,description,parent,type)
+  VALUES('org.openecomp.dmaapBC',3,'Application Authorization Framework','org.openecomp',3);
+
+//INSERT INTO role(ns, name, perms, description)
+//  VALUES('org.openecomp.dmaapBC','admin',{'org.openecomp.dmaapBC.access|*|*'},'AAF Admins');
+
+INSERT INTO role(ns, name, perms, description) 
+VALUES('org.openecomp.dmaapBC','admin',{'org.openecomp.dmaapBC.access|*|*','org.openecomp.dmaapBC.topicFactory|:org.openecomp.dmaapBC.topic:org.openecomp.dmaapBC|create','org.openecomp.dmaapBC.mr.topic|:topic.org.openecomp.dmaapBC.newtopic|sub','org.openecomp.dmaapBC.mr.topic|:topic.org.openecomp.dmaapBC.newtopic|pub'},'AAF Admins');
+
+//INSERT INTO role(ns, name, perms, description) 
+//VALUES('org.openecomp.dmaapBC','admin',{'org.openecomp.dmaapBC.access|*|*','org.openecomp.dmaapBC.mr.topic|:topic.org.openecomp.dmaapBC.newtopic|sub'},'AAF Admins');
+
+//INSERT INTO role(ns, name, perms, description) 
+//VALUES('org.openecomp.dmaapBC','admin',{'org.openecomp.dmaapBC.access|*|*','org.openecomp.dmaapBC.mr.topic|:topic.org.openecomp.dmaapBC.newtopic|pub'},'AAF Admins');
+
+
+
+INSERT INTO role(ns, name, perms, description)
+  VALUES('org.openecomp.dmaapBC','owner',{'org.openecomp.dmaapBC.access|*|read'},'AAF Owners');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp.dmaapBC','access','*','read',{'org.openecomp.dmaapBC.owner'},'AAF Read Access');
+
+INSERT INTO perm(ns, type, instance, action, roles, description) 
+  VALUES ('org.openecomp.dmaapBC','access','*','*',{'org.openecomp.dmaapBC.admin'},'AAF Write Access');
+
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.openecomp.dmaapBC.admin','2020-12-31','org.openecomp.dmaapBC','admin');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('dgl@openecomp.org','org.openecomp.dmaapBC.owner','2020-12-31','org.openecomp.dmaapBC','owner');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('m99751@dmaapBC.openecomp.org','org.openecomp.dmaapBC.admin','2020-12-31','org.openecomp.dmaapBC','admin');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('m99751@dmaapBC.openecomp.org','org.openecomp.dmaapBC.owner','2020-12-31','org.openecomp.dmaapBC','owner');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('m99501@dmaapBC.openecomp.org','org.openecomp.dmaapBC.admin','2020-12-31','org.openecomp.dmaapBC','admin');
+INSERT INTO user_role(user,role,expires,ns,rname)
+  VALUES ('m99501@dmaapBC.openecomp.org','org.openecomp.dmaapBC.owner','2020-12-31','org.openecomp.dmaapBC','owner');
diff --git a/authz-service/src/main/resources/docker-compose/data/identities.dat b/authz-service/src/main/resources/docker-compose/data/identities.dat
new file mode 100644
index 0000000..98bf99a
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/data/identities.dat
@@ -0,0 +1,7 @@
+iowna|Ima D. Owner|Ima|Owner|314-123-2000|ima.d.owner@osaaf.com|e|
+mmanager|Mark D. Manager|Mark|Manager|314-123-1234|mark.d.manager@osaaf.com|e|iowna
+bdevl|Robert D. Developer|Bob|Developer|314-123-1235|bob.d.develper@osaaf.com|e|mmanager
+mmarket|Mary D. Marketer|Mary|Marketer|314-123-1236|mary.d.marketer@osaaf.com|e|mmanager
+ccontra|Clarice D. Contractor|Clarice|Contractor|314-123-1237|clarice.d.contractor@osaaf.com|c|mmanager
+iretired|Ira Lee M. Retired|Ira|Retired|314-123-1238|clarice.d.contractor@osaaf.com|n|mmanager
+osaaf|ID of AAF|||||a|bdevl
diff --git a/authz-service/src/main/resources/docker-compose/data/identities.idx b/authz-service/src/main/resources/docker-compose/data/identities.idx
new file mode 100644
index 0000000..78fc0a5
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/data/identities.idx
Binary files differ
diff --git a/authz-service/src/main/resources/docker-compose/data/init.cql b/authz-service/src/main/resources/docker-compose/data/init.cql
new file mode 100644
index 0000000..81700f8
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/data/init.cql
@@ -0,0 +1,242 @@
+// For Developer Machine single instance
+//
+CREATE KEYSPACE authz
+WITH REPLICATION = {'class' : 'SimpleStrategy','replication_factor':1};
+// 
+// From Ravi, 6-17-2014.  User for DEVL->TEST
+//
+// CREATE KEYSPACE authz WITH replication = { 'class': 'NetworkTopologyStrategy', 'HYWRCA02': '2', 'BRHMALDC': '2' };
+// 
+// PROD
+// 
+// CREATE KEYSPACE authz WITH replication = {'class': 'NetworkTopologyStrategy','ALPSGACT': '2','STLSMORC': '2','BRHMALDC': '2' };
+//
+//  create user authz with password '<AUTHZ PASSWORD>' superuser;
+//  grant all on keyspace authz to authz;
+//
+// For TEST (aaf_test)
+// CREATE KEYSPACE authz WITH replication = { 'class': 'NetworkTopologyStrategy', 'BRHMALDC': '1' };
+//
+// DEVL
+// CREATE KEYSPACE authz WITH replication = {'class': 'NetworkTopologyStrategy','STLSMORC': '2' };
+//
+// TEST / PERF
+// CREATE KEYSPACE authz WITH replication = {'class': 'NetworkTopologyStrategy','STLSMORC': '3','KGMTNC20': '3' };
+//
+// IST
+// CREATE KEYSPACE authz WITH replication = {'class': 'NetworkTopologyStrategy','STLSMORC':'3',
+// 'DLLSTXCF':'3','KGMTNC20':'3','SFLDMIBB':'3','HYWRCA02':'3' };
+//
+// with 6 localized with ccm
+// CREATE KEYSPACE authz WITH replication = { 'class': 'NetworkTopologyStrategy', 'dc1': '2', 'dc2': '2' };
+// 
+
+USE authz;
+
+//
+// CORE Table function
+//
+
+// Namespace - establish hierarchical authority to modify
+// Permissions and Roles
+// "scope" is flag to determine Policy.  Typical important scope
+// is "company" (1)
+CREATE TABLE ns (
+  name			varchar,
+  scope			int,  // deprecated 2.0.11
+  description   	varchar,
+  parent 		varchar,
+  type			int,
+  PRIMARY KEY (name)  
+);
+CREATE INDEX ns_parent on ns(parent);
+  
+
+// Oct 2015, not performant.  Made Owner and Attrib first class Roles,
+// April, 2015.  Originally, the plan was to utilize Cassandra 2.1.2, however, other team's preferences were to remain at current levels.
+// Therefore, we are taking the separate table approach.  (coder Jeremiah Rohwedder)
+// We had dropped this by making first class objects of Responsible (Owner) and Admin.  We need this again to mark namespaces
+// as having certain tools, like SWM, etc.
+CREATE TABLE ns_attrib (
+  ns            varchar,
+  key           varchar,
+  value         varchar,
+  PRIMARY KEY (ns,key)
+);
+create index ns_attrib_key on ns_attrib(key);
+
+// Will be cached
+CREATE TABLE role (
+  ns	    varchar,
+  name		varchar,
+  perms		set<varchar>, // Use "Key" of "name|type|action"
+  description varchar,
+  PRIMARY KEY (ns,name)
+);
+CREATE INDEX role_name  ON role(name);
+ 
+// Will be cached
+CREATE TABLE perm (
+  ns	    varchar,
+  type 		varchar,
+  instance	varchar,
+  action	varchar,
+  roles		set<varchar>, // Need to find Roles given Permissions
+  description varchar,
+  PRIMARY KEY (ns,type,instance,action)
+);
+
+// This table is user for Authorization
+CREATE TABLE user_role (
+    user		varchar,
+    role		varchar, // deprecated: change to ns/rname after 2.0.11
+    ns			varchar,
+    rname		varchar,
+    expires		timestamp,
+    PRIMARY KEY(user,role)
+  );
+CREATE INDEX user_role_ns ON user_role(ns);
+CREATE INDEX user_role_role ON user_role(role);
+
+// This table is only for the case where return User Credential (MechID) Authentication
+CREATE TABLE cred (
+    id    varchar,
+    type  int,
+    expires timestamp,  
+    ns    varchar,
+    other int,
+    notes varchar,
+    cred  blob,
+    prev  blob,
+    PRIMARY KEY (id,type,expires)
+  );
+CREATE INDEX cred_ns ON cred(ns);
+
+// Certificate Cross Table
+//   coordinated with CRED type 2
+CREATE TABLE cert (
+    fingerprint blob,
+    id    	varchar,
+    x500	varchar,
+    expires 	timestamp,  
+    PRIMARY KEY (fingerprint)
+  );
+CREATE INDEX cert_id ON cert(id);
+CREATE INDEX cert_x500 ON cert(x500);
+
+CREATE TABLE notify (
+  user text,
+  type int,
+  last timestamp,
+  checksum int,
+  PRIMARY KEY (user,type)
+);
+
+CREATE TABLE x509 (
+  ca     text,
+  serial blob,
+  id     text,
+  x500   text,
+  x509   text,
+  PRIMARY KEY (ca,serial)
+);
+
+
+CREATE INDEX x509_id   ON x509 (id);
+CREATE INDEX x509_x500 ON x509 (x500);
+
+// 
+// Deployment Artifact (for Certman)
+//
+CREATE TABLE artifact (
+  mechid        text,
+  machine       text,
+  type          Set<text>,
+  sponsor       text,
+  ca            text,
+  dir           text,
+  appName       text,
+  os_user       text,
+  notify        text,
+  expires	timestamp,
+  renewDays   int,
+  PRIMARY KEY (mechid,machine)
+);
+CREATE INDEX artifact_machine ON artifact(machine); 
+
+//
+// Non-Critical Table functions
+//
+// Table Info - for Caching
+CREATE TABLE cache (
+   name		varchar,
+   seg		int, 		// cache Segment
+   touched	timestamp,
+   PRIMARY KEY(name,seg)
+);
+
+CREATE TABLE history (
+  id			timeuuid,
+  yr_mon		int,
+  user			varchar,
+  action 		varchar,
+  target		varchar,   // user, user_role, 
+  subject		varchar,   // field for searching main portion of target key
+  memo			varchar,   //description of the action
+  reconstruct 	blob,      //serialized form of the target
+  // detail 	Map<varchar, varchar>,  // additional information
+  PRIMARY KEY (id)
+);
+CREATE INDEX history_yr_mon ON history(yr_mon);
+CREATE INDEX history_user ON history(user); 
+CREATE INDEX history_subject ON history(subject); 
+
+// 
+// A place to hold objects to be created at a future time.
+//
+CREATE TABLE future (
+  id        uuid,  		// uniquify
+  target    varchar,   		// Target Table
+  memo	    varchar,    	// Description
+  start     timestamp, 		// When it should take effect
+  expires   timestamp, 		// When not longer valid
+  construct blob, 		// How to construct this object (like History)
+  PRIMARY KEY(id)
+);
+CREATE INDEX future_idx ON future(target);
+CREATE INDEX future_start_idx ON future(start);
+
+
+CREATE TABLE approval (
+  id	    timeuuid,	      // unique Key
+  ticket    uuid,	      // Link to Future Record
+  user 	    varchar,          // the user who needs to be approved
+  approver  varchar, 	      // user approving
+  type      varchar,          // approver types i.e. Supervisor, Owner
+  status    varchar,          // approval status. pending, approved, denied
+  memo      varchar,          // Text for Approval to know what's going on
+  operation varchar,	      // List operation to perform
+  PRIMARY KEY(id)
+ );
+CREATE INDEX appr_approver_idx ON approval(approver);
+CREATE INDEX appr_user_idx ON approval(user);
+CREATE INDEX appr_ticket_idx ON approval(ticket);
+CREATE INDEX appr_status_idx ON approval(status);
+
+CREATE TABLE delegate (
+  user      varchar,
+  delegate  varchar,
+  expires   timestamp,
+  PRIMARY KEY (user)  
+);
+CREATE INDEX delg_delg_idx ON delegate(delegate);
+
+//
+// Used by authz-batch processes to ensure only 1 runs at a time
+//
+CREATE TABLE run_lock (
+  class text,
+  host text,
+  start timestamp,
+  PRIMARY KEY ((class))
+);
diff --git a/authz-service/src/main/resources/docker-compose/data2/identities.dat b/authz-service/src/main/resources/docker-compose/data2/identities.dat
new file mode 100644
index 0000000..95eb51d
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/data2/identities.dat
@@ -0,0 +1,9 @@
+iowna|Ima D. Owner|Ima|Owner|314-123-2000|ima.d.owner@osaaf.com|e|
+mmanager|Mark D. Manager|Mark|Manager|314-123-1234|mark.d.manager@osaaf.com|e|iowna
+bdevl|Robert D. Developer|Bob|Developer|314-123-1235|bob.d.develper@osaaf.com|e|mmanager
+mmarket|Mary D. Marketer|Mary|Marketer|314-123-1236|mary.d.marketer@osaaf.com|e|mmanager
+ccontra|Clarice D. Contractor|Clarice|Contractor|314-123-1237|clarice.d.contractor@osaaf.com|c|mmanager
+iretired|Ira Lee M. Retired|Ira|Retired|314-123-1238|clarice.d.contractor@osaaf.com|n|mmanager
+osaaf|ID of AAF|||||a|bdevl
+m99751|ID of AAF|||||a|bdevl
+m99501|ID of AAF|||||a|bdevl
diff --git a/authz-service/src/main/resources/docker-compose/docker-compose.yml b/authz-service/src/main/resources/docker-compose/docker-compose.yml
new file mode 100644
index 0000000..fce6824
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/docker-compose.yml
@@ -0,0 +1,58 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+version: '2'

+services:

+  aaf_container:

+    image: attos/aaf

+    ports:

+      - "8101:8101"

+

+    links:

+      - cassandra_container

+    volumes:

+    # - ./authAPI.props:/opt/app/aaf/authz-service/2.0.15/etc/authAPI.props

+      - ./wait_for_host_port.sh:/tmp/wait_for_host_port.sh

+      - ./data2:/data

+      - ./runaafcli.sh:/opt/app/aaf/authz-service/2.0.15/runaafcli.sh

+    #  - ./com.osaaf.common.props:/opt/app/aaf/authz-service/2.0.15/etc/com.osaaf.common.props

+    # - ./cadi-core-1.3.0.jar:/opt/app/aaf/authz-service/2.0.15/lib/cadi-core-1.3.0.jar

+    #  - ./cadi-aaf-1.3.0.jar:/opt/app/aaf/authz-service/2.0.15/lib/cadi-aaf-1.3.0.jar

+    # - ./cadi-client-1.3.0.jar:/opt/app/aaf/authz-service/2.0.15/lib/cadi-client-1.3.0.jar

+    # - ./authz-service-2.0.15.jar:/opt/app/aaf/authz-service/2.0.15/lib/authz-service-2.0.15.jar

+    #  - ./dme2-3.1.200.jar:/opt/app/aaf/authz-service/2.0.15/lib/dme2-3.1.200.jar

+    entrypoint: ["bash", "-c", "/tmp/wait_for_host_port.sh cassandra_container 9042; sleep 20; /bin/sh -c ./startup.sh"]

+    environment:

+      - CASSANDRA_CLUSTER=cassandra_container

+    

+

+  cassandra_container:

+    image: cassandra:2.1.16

+    ports:

+      - "7000:7000"

+      - "7001:7001"

+      - "9042:9042"

+      - "9160:9160"

+    volumes:

+      - ./data:/data

+      - ./wait_for_host_port.sh:/tmp/wait_for_host_port.sh

+    entrypoint: ["bash", "-c", "(/tmp/wait_for_host_port.sh localhost 9042 cqlsh --file /data/init.cql -u cassandra -p cassandra localhost; cqlsh --file /data/ecomp.cql -u cassandra -p cassandra localhost) & (/docker-entrypoint.sh cassandra -f)"]

diff --git a/authz-service/src/main/resources/docker-compose/old/dme2-3.1.200.jar b/authz-service/src/main/resources/docker-compose/old/dme2-3.1.200.jar
new file mode 100644
index 0000000..213fb9c
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/old/dme2-3.1.200.jar
Binary files differ
diff --git a/authz-service/src/main/resources/docker-compose/runaafcli.sh b/authz-service/src/main/resources/docker-compose/runaafcli.sh
new file mode 100644
index 0000000..a4ce518
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/runaafcli.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+DIR=`pwd` 
+#DME2REG=$DIR/../dme2reg 
+DME2REG=/opt/dme2reg 
+#CLASSPATH=etc:target/authz-cmd-2.0.15-jar-with-dependencies.jar  
+CLASSPATH=/opt/app/aaf/authz-service/2.0.15/etc:/opt/app/aaf/authz-service/2.0.15/lib/authz-cmd-2.0.15-jar-with-dependencies.jar  
+#java -cp $CLASSPATH -Dcadi_prop_files=../authz-service/src/main/sample/authAPI.props -DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG com.att.cmd.AAFcli $*
+java -cp $CLASSPATH -Dcadi_prop_files=/opt/app/aaf/authz-service/2.0.15/etc/authAPI.props -DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG com.att.cmd.AAFcli $*
diff --git a/authz-service/src/main/resources/docker-compose/startupaaf.sh b/authz-service/src/main/resources/docker-compose/startupaaf.sh
new file mode 100644
index 0000000..bc1f0b2
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/startupaaf.sh
@@ -0,0 +1,32 @@
+# lji: this startup file shadows the existing extry point startup.sh file of the container
+# because we need to pass in the cassandra cluster location 
+
+LIB=/opt/app/aaf/authz-service/2.0.15/lib
+
+ETC=/opt/app/aaf/authz-service/2.0.15/etc
+DME2REG=/opt/dme2reg
+
+echo "this is LIB" $LIB
+echo "this is ETC" $ETC
+echo "this is DME2REG" $DME2REG
+
+CLASSPATH=$ETC
+for FILE in `find $LIB -name *.jar`; do
+  CLASSPATH=$CLASSPATH:$FILE
+done
+
+FILEPATHS="/opt/app/aaf/common/com.osaaf.common.props /opt/app/aaf/authz-service/2.0.15/etc/com.osaaf.common.props"
+for FILEPATH in $FILEPATHS: 
+do 
+  if [ -e ${FILEPATH} ]; then
+    if [ -z `grep "cassandra.clusters=$CASSANDRA_CLUSTER" $FILEPATH` ]; then 
+      echo "cassandra.clusters=$CASSANDRA_CLUSTER" >> $FILEPATH; 
+    fi
+  fi
+done
+
+
+java -classpath $CLASSPATH -DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG com.att.authz.service.AuthAPI
+
+# keet it running so we can check fs
+while sleep 2; do echo thinking; done
diff --git a/authz-service/src/main/resources/docker-compose/sysctl.conf b/authz-service/src/main/resources/docker-compose/sysctl.conf
new file mode 100644
index 0000000..c36fd68
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/sysctl.conf
@@ -0,0 +1,3 @@
+net.ipv6.conf.all.disable_ipv6=1
+net.ipv6.conf.default.disable_ipv6=1
+net.ipv6.conf.lol.disable_ipv6=1
diff --git a/authz-service/src/main/resources/docker-compose/wait_for_host_port.sh b/authz-service/src/main/resources/docker-compose/wait_for_host_port.sh
new file mode 100644
index 0000000..e4e4bf9
--- /dev/null
+++ b/authz-service/src/main/resources/docker-compose/wait_for_host_port.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+host="$1"
+port="$2"
+shift
+shift
+cmd="$@"
+
+until echo > /dev/tcp/${host}/${port} ; do
+  >&2 echo "${host}:${port} is unavailable - sleeping"
+  sleep 1
+done
+
+>&2 echo "${host}:${port} is up - executing command"
+exec $cmd
diff --git a/authz-service/src/main/sample/authAPI.props b/authz-service/src/main/sample/authAPI.props
new file mode 100644
index 0000000..d2e2f62
--- /dev/null
+++ b/authz-service/src/main/sample/authAPI.props
@@ -0,0 +1,30 @@
+##
+## AUTHZ API (authz-service) Properties
+##
+
+# Standard AFT for THIS box, and THIS box is in St Louis.  Put your own LAT/LONG in here.  Use "bing.com/maps" or 
+# SWMTools (geoloc for DataCenters) to get YOURs
+
+AFT_LATITUDE=32.780140
+AFT_LONGITUDE=-96.800451
+AFT_ENVIRONMENT=AFTUAT
+DEPLOYED_VERSION=2.0.SAMPLE
+
+##DME2 related parameters
+DMEServiceName=service=com.att.authz.AuthorizationService/version=2.0/envContext=DEV/routeOffer=BAU_SE
+
+#DME2 can limit Port Ranges with the following:
+# AFT_DME2_PORT_RANGE=8101-8029,8100
+# Leaving both unset makes DME2 picks any unused port in +1024 range (Ephemeral)
+# AFT_DME2_PORT=0
+AFT_DME2_ALLOW_PORT_CACHING=false
+
+# Point to "Common" files, used between all the AAF Services. ... 
+cadi_prop_files=../opt/app/aaf/common/com.osaaf.common.props;../opt/app/aaf/common/com.osaaf.props
+
+CACHE_HIGH_COUNT=40000
+CACHE_CLEAN_INTERVAL=60000
+
+
+
+
diff --git a/authz-service/src/main/sample/log4j.properties b/authz-service/src/main/sample/log4j.properties
new file mode 100644
index 0000000..b1976ed
--- /dev/null
+++ b/authz-service/src/main/sample/log4j.properties
@@ -0,0 +1,85 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+#

+# 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.appender.INIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.INIT.File=logs/${LOG4J_FILENAME_init}

+log4j.appender.INIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.INIT.MaxFileSize=10000KB

+#log4j.appender.INIT.MaxBackupIndex=7

+log4j.appender.INIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.INIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.SRVR=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.SRVR.File=logs/${LOG4J_FILENAME_authz}

+log4j.appender.SRVR.DatePattern='.'yyyy-MM-dd

+#log4j.appender.SRVR.MaxFileSize=10000KB

+#log4j.appender.SRVR.MaxBackupIndex=7

+log4j.appender.SRVR.layout=org.apache.log4j.PatternLayout 

+log4j.appender.SRVR.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %p [%c] %m %n

+

+log4j.appender.AUDIT=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.AUDIT.File=logs/${LOG4J_FILENAME_audit}

+log4j.appender.AUDIT.DatePattern='.'yyyy-MM-dd

+#log4j.appender.AUDIT.MaxFileSize=10000KB

+#log4j.appender.AUDIT.MaxBackupIndex=7

+log4j.appender.AUDIT.layout=org.apache.log4j.PatternLayout 

+log4j.appender.AUDIT.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.TRACE=org.apache.log4j.DailyRollingFileAppender

+log4j.appender.TRACE.File=logs/${LOG4J_FILENAME_trace}

+log4j.appender.TRACE.DatePattern='.'yyyy-MM-dd

+log4j.appender.TRACE.MaxFileSize=10000KB

+log4j.appender.TRACE.MaxBackupIndex=7

+log4j.appender.TRACE.layout=org.apache.log4j.PatternLayout 

+log4j.appender.TRACE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %m %n

+

+log4j.appender.stdout=org.apache.log4j.ConsoleAppender

+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

+log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSSZ} %p [%c] %m %n

+

+# General Apache libraries

+log4j.rootLogger=WARN

+log4j.logger.org.apache=WARN,INIT

+log4j.logger.dme2=WARN,INIT

+log4j.logger.init=WARN,stdout,INIT

+log4j.logger.authz=WARN,stdout,SRVR

+log4j.logger.audit=WARN,AUDIT

+log4j.logger.trace=TRACE,TRACE

+

diff --git a/authz-service/src/main/swm/common/deinstall.sh b/authz-service/src/main/swm/common/deinstall.sh
new file mode 100644
index 0000000..740564c
--- /dev/null
+++ b/authz-service/src/main/swm/common/deinstall.sh
@@ -0,0 +1,40 @@
+#!/bin/sh

+##############################################################################

+# - Copyright 2012, 2016 AT&T Intellectual Properties

+##############################################################################
+umask 022

+ROOT_DIR=${INSTALL_ROOT}/${distFilesRootDirPath}

+

+# Grab the IID of all resources running under the name and same version(s) we're working on and stop those instances

+${LRM_HOME}/bin/lrmcli -running | \

+	grep ${artifactId} | \

+	grep ${version} | \

+	cut -f1 | \

+while read _iid

+do

+	if [ -n "${_iid}" ]; then

+		${LRM_HOME}/bin/lrmcli -shutdown -iid ${_iid} | grep SUCCESS

+		if [ $? -ne 0 ]; then

+			echo "$LRMID-{_iid} Shutdown failed"

+		fi

+	fi

+done

+	

+# Grab the resources configured under the name and same version we're working on and delete those instances

+${LRM_HOME}/bin/lrmcli -configured | \

+	grep ${artifactId} | \

+	grep ${version} | \

+	cut -f1,2,3 | \

+while read _name _version _routeoffer

+do

+	if [ -n "${_name}" ]; then

+		${LRM_HOME}/bin/lrmcli -delete -name ${_name} -version ${_version} -routeoffer ${_routeoffer} | grep SUCCESS

+		if [ $? -ne 0 ]; then

+			echo "${_version} Delete failed"

+		fi

+	fi

+done	

+

+rm -rf ${ROOT_DIR}

+

+exit 0

diff --git a/authz-service/src/main/swm/common/install.sh b/authz-service/src/main/swm/common/install.sh
new file mode 100644
index 0000000..b5c3201
--- /dev/null
+++ b/authz-service/src/main/swm/common/install.sh
@@ -0,0 +1,252 @@
+#!/bin/sh
+##############################################################################
+# AAF Installs
+# - Copyright 2015, 2016 AT&T Intellectual Properties
+##############################################################################
+umask 022
+ROOT_DIR=${INSTALL_ROOT}${distFilesRootDirPath}
+COMMON_DIR=${INSTALL_ROOT}${distFilesRootDirPath}/../../common
+LRM_XML=${ROOT_DIR}/etc/lrm-${artifactId}.xml
+LOGGING_PROP_FILE=${ROOT_DIR}/etc/log4j.properties
+LOGGER_PROP_FILE=${ROOT_DIR}/etc/logging.props
+AAFLOGIN=${ROOT_DIR}/bin/aaflogin
+JAVA_HOME=/opt/java/jdk/jdk180
+JAVA=$JAVA_HOME/bin/java
+CADI_JAR=`ls $ROOT_DIR/lib/cadi-core*.jar`
+
+cd ${ROOT_DIR}
+
+mkdir -p logs || fail 1 "Error on creating the logs directory."
+mkdir -p back || fail 1 "Error on creating the back directory."
+chmod 777 back || fail 1 "Error on creating the back directory."
+
+# 
+# Some Functions that Vastly cleanup this install file...
+# You wouldn't believe how ugly it was before.  Unreadable... JG 
+#
+fail() {
+	rc=$1
+	shift;
+    echo "ERROR: $@"
+    exit $rc
+}
+
+#
+# Set the "SED" replacement for this Variable.  Error if missing
+# Note that Variable in the Template is surrounded by "_" i.e. _ROOT_DIR_
+#   Replacement Name
+#   Value
+#
+required() {
+	if [ -z "$2" ]; then
+	  ERRS+="\n\t$1 must be set for this installation"
+	fi
+	SED_E+=" -e s|$1|$2|g"
+}
+
+#
+# Set the "SED" replacement for this Variable. Use Default (3rd parm) if missing
+# Note that Variable in the Template is surrounded by "_" i.e. _ROOT_DIR_
+#   Replacement Name
+#   Value
+#   Default Value
+#
+default() {
+    if [ -z "$2" ]; then
+    	SED_E+=" -e s|$1|$3|g"
+    else 
+    	SED_E+=" -e s|$1|$2|g"
+    fi
+}
+
+# 
+# Password behavior:
+#     For each Password passed in:
+#       If Password starts with "enc:???", then replace it as is
+#       If not, then check for CADI_KEYFILE... see next
+#     If the CADI_KEYFILE is set, the utilize this as the CADI Keyfile
+#     	If it does not exist, create it, and change to "0400" mode
+#     Utilize the Java and "cadi-core" found in Library to
+#       Encrypt Password with Keyfile, prepending "enc:???"
+#
+passwd() {
+  #
+  # Test if var exists, and is required
+  #
+  if [ "${!1}" = "" ]; then
+    if [ "${2}" = "required" ]; then
+     	ERRS+="\n\t$1 must be set for this installation" 
+    fi
+  else
+    #
+    # Test if needs encrypting
+    #
+    if [[ ${!1} = enc:* ]]; then
+      SED_E+=" -e s|_${1}_|${!1}|g"
+    else
+      if [ "${CADI_KEYFILE}" != "" ]  &&  [ -e "${CADI_JAR}" ]; then
+        #
+        # Create or use Keyfile listed in CADI_KEYFILE
+        #
+        if [ -e "${CADI_KEYFILE}" ]; then
+          if [ "$REPORTED_CADI_KEYFILE" = "" ]; then
+            echo "Using existing CADI KEYFILE (${CADI_KEYFILE})"
+            REPORTED_CADI_KEYFILE=true
+          fi
+        else
+           echo "Creating CADI_KEYFILE (${CADI_KEYFILE})"
+           $JAVA -jar $CADI_JAR keygen ${CADI_KEYFILE}
+           chmod 0400 ${CADI_KEYFILE}
+        fi
+
+        PASS=`$JAVA -jar $CADI_JAR digest ${!1} ${CADI_KEYFILE}`
+        SED_E+=" -e s|_${1}_|enc:$PASS|g"
+      else
+        if [ "$REPORTED_CADI_KEYFILE" = "" ]; then
+          if [ "${CADI_KEYFILE}" = "" ]; then
+            ERRS+="\n\tCADI_KEYFILE must be set for this installation" 
+          fi
+          if [ ! -e "${CADI_JAR}" ]; then
+            ERRS+="\n\t${CADI_JAR} must exist to deploy passwords"
+          fi
+          REPORTED_CADI_KEYFILE=true
+        fi
+      fi
+    fi
+  fi
+}
+
+# Linux requires this.  Mac blows with it.  Who knows if Windoze even does SED
+if [ -z "$SED_OPTS" ]; then
+	SED_E+=" -c "
+else
+	SED_E+=$SED_OPTS;
+fi 
+
+# 
+# Use "default" function if there is a property that isn't required, but can be defaulted
+# use "required" function if the property must be set by the environment
+#
+	required _ROOT_DIR_ ${ROOT_DIR}
+	default _COMMON_DIR_ ${AUTHZ_COMMON_DIR} ${COMMON_DIR}
+	required _JAVA_HOME_ ${JAVA_HOME}
+	required _SCLD_PLATFORM_ ${SCLD_PLATFORM}
+	required _HOSTNAME_ ${TARGET_HOSTNAME_FQ}
+	required _ARTIFACT_ID_ ${artifactId}
+	default _ARTIFACT_VERSION_ ${AFTSWM_ACTION_NEW_VERSION}
+	default _RESOURCE_REGISTRATION_ ${RESOURCE_REGISTRATION} true
+	default _AUTHZ_DATA_DIR_ ${AUTHZ_DATA_DIR} ${ROOT_DIR}/../../data
+	default _CM_URL_ ${CM_URL} ""
+	
+	# Specifics for Service
+	if [ "${artifactId}" = "authz-service" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/authAPI.props
+		default _RESOURCE_MIN_COUNT_ ${RESOURCE_MIN_COUNT} 1
+		default _RESOURCE_MAX_COUNT_ ${RESOURCE_MAX_COUNT} 5
+		required _AUTHZ_SERVICE_PORT_RANGE_ ${AUTHZ_SERVICE_PORT_RANGE}
+		
+	elif [ "${artifactId}" = "authz-gui" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/authGUI.props
+		required _AUTHZ_GUI_PORT_RANGE_ ${AUTHZ_GUI_PORT_RANGE}
+		default _RESOURCE_MIN_COUNT_ ${RESOURCE_MIN_COUNT} 1
+		default _RESOURCE_MAX_COUNT_ ${RESOURCE_MAX_COUNT} 2
+
+	elif [ "${artifactId}" = "authz-gw" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/authGW.props
+		default _AUTHZ_GW_PORT_RANGE_ ${AUTHZ_GW_PORT_RANGE} 8095-8095
+		default _RESOURCE_MIN_COUNT_ 1
+		default _RESOURCE_MAX_COUNT_ 1
+
+	elif [ "${artifactId}" = "authz-fs" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/FileServer.props
+		OTHER_FILES=${ROOT_DIR}/data/test.html
+		default _AUTHZ_FS_PORT_RANGE_ ${AUTHZ_FS_PORT_RANGE} 8096-8096
+		default _RESOURCE_MIN_COUNT_ 1
+		default _RESOURCE_MAX_COUNT_ 1
+
+	elif [ "${artifactId}" = "authz-certman" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/certman.props
+		default _AUTHZ_CERTMAN_PORT_RANGE_ ${AUTHZ_CERTMAN_PORT_RANGE} 8150-8159
+		default _RESOURCE_MIN_COUNT_ 1
+		default _RESOURCE_MAX_COUNT_ 1
+	elif [ "${artifactId}" = "authz-batch" ]; then
+		PROPERTIES_FILE=${ROOT_DIR}/etc/authBatch.props
+		cd /
+		OTHER_FILES=`find ${ROOT_DIR}/bin -depth -type f`
+		cd -
+		default _RESOURCE_MIN_COUNT_ 1
+		default _RESOURCE_MAX_COUNT_ 1
+		required _AUTHZ_GUI_URL_ ${AUTHZ_GUI_URL}
+	else
+		PROPERTIES_FILE=NONE
+	fi
+
+	if [ "${DME2_FS}" != "" ]; then
+		SED_E+=" -e s|_DME2_FS_|-DDME2_EP_REGISTRY_CLASS=DME2FS\$\{AAF_SPACE\}-DAFT_DME2_EP_REGISTRY_FS_DIR=${DME2_FS}|g"
+	else
+		SED_E+=" -e s|_DME2_FS_||g"
+	fi
+	
+
+	default _EMAIL_FROM_ ${EMAIL_FROM} authz@ems.att.com
+    default _EMAIL_HOST_ ${EMAIL_HOST} mailhost.att.com
+	default _ROUTE_OFFER_ ${ROUTE_OFFER} BAU_SE
+	default _DME_TIMEOUT_ ${DME_TIMEOUT} 3000
+
+	# Choose defaults for log level and logfile size
+	if [ "${SCLD_PLATFORM}" = "PROD" ]; then
+	        LOG4J_LEVEL=WARN
+	fi
+
+	default _AFT_ENVIRONMENT_ ${AFT_ENVIRONMENT} AFTUAT
+	default _ENV_CONTEXT_ ${ENV_CONTEXT} DEV
+	default _LOG4J_LEVEL_ ${LOG4J_LEVEL} WARN  
+	default _LOG4J_SIZE_ ${LOG4J_SIZE} 10000KB
+	default _LOG_DIR_ ${LOG_DIR} ${ROOT_DIR}/logs
+	default _MAX_LOG_FILE_SIZE_ ${MAX_LOG_FILE_SIZE} 10000KB
+	default _MAX_LOG_FILE_BACKUP_COUNT_ ${MAX_LOG_FILE_BACKUP_COUNT} 7
+
+	if [ "${artifactId}" != "authz-batch" ]; then
+		required _LRM_XML_ ${LRM_XML}
+	fi
+	required _AFT_LATITUDE_ ${LATITUDE}
+	required _AFT_LONGITUDE_ ${LONGITUDE}
+	required _HOSTNAME_ ${HOSTNAME}
+
+	required _PROPERTIES_FILE_ ${PROPERTIES_FILE}
+	required _LOGGING_PROP_FILE_ ${LOGGING_PROP_FILE}
+	
+	# Divide up Version
+	default _MAJOR_VER_ "`expr ${version} : '\([0-9]*\)\..*'`"
+	default _MINOR_VER_ "`expr ${version} : '[0-9]*\.\([0-9]*\)\..*'`"
+	default _PATCH_VER_ "`expr ${version} : '[0-9]\.[0-9]*\.\(.*\)'`"
+
+# Now Fail if Required items are not set... 
+# Report all of them at once!
+if [ "${ERRS}" != "" ] ; then
+	fail 1 "${ERRS}"
+fi
+
+#echo ${SED_E}
+
+for i in ${PROPERTIES_FILE} ${LRM_XML} ${LOGGING_PROP_FILE} ${AAFLOGIN} ${OTHER_FILES} ; do
+  if [ -r ${i} ]; then
+	  if [ -w ${i} ]; then
+#	  	echo ${i}
+	     sed ${SED_E} -i'.sed' ${i} || fail 8 "could not sed ${i} "
+	     mv -f ${i}.sed ${ROOT_DIR}/back
+	   fi
+	fi
+done
+
+#
+# Add the resource to LRM using the newly created/substituted XML file.
+#
+if [ -r ${LRM_XML} ]; then
+	${LRM_HOME}/bin/lrmcli -addOrUpgrade -file ${LRM_XML} || fail 1 "Add to LRM Failed"
+	${LRM_HOME}/bin/lrmcli -start -name com.att.authz.${artifactId} -version ${version} -routeoffer ${ROUTE_OFFER} | grep SUCCESS
+fi
+
+
+# Note: Must exit 0 or, it will be exit default 1 and fail
+exit 0
diff --git a/authz-service/src/main/swm/deinstall/postproc/post_proc b/authz-service/src/main/swm/deinstall/postproc/post_proc
new file mode 100644
index 0000000..beec0a2
--- /dev/null
+++ b/authz-service/src/main/swm/deinstall/postproc/post_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+#!/bin/sh
+exit 0
\ No newline at end of file
diff --git a/authz-service/src/main/swm/deinstall/preproc/pre_proc b/authz-service/src/main/swm/deinstall/preproc/pre_proc
new file mode 100644
index 0000000..2a6a529
--- /dev/null
+++ b/authz-service/src/main/swm/deinstall/preproc/pre_proc
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec sh -x ../../common/deinstall.sh
diff --git a/authz-service/src/main/swm/descriptor.xml b/authz-service/src/main/swm/descriptor.xml
new file mode 100644
index 0000000..c262524
--- /dev/null
+++ b/authz-service/src/main/swm/descriptor.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<descriptor version="1" xmlns="http://aft.att.com/swm/descriptor">

+	<platforms>

+		<platform architecture="*" os="*" osVersions="*"/> 

+	</platforms>

+	<paths>

+		<path name="/opt/app/aaf" type="d" user="aft" group="aft" permissions="0755" recursive="false"/>

+		<path name="/opt/app/aaf/${artifactId}" type="d" user="aft" group="aft" permissions="0755" recursive="false"/>

+		<path name="/opt/app/aaf/${artifactId}/${version}" type="d" user="aft" group="aft" permissions="0755" recursive="true"/>

+	</paths>

+	<actions>

+		<action type="INIT">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="INST">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="DINST">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="FALL">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+	</actions>

+</descriptor>

diff --git a/authz-service/src/main/swm/fallback/postproc/post_proc b/authz-service/src/main/swm/fallback/postproc/post_proc
new file mode 100644
index 0000000..3eb8e6d
--- /dev/null
+++ b/authz-service/src/main/swm/fallback/postproc/post_proc
@@ -0,0 +1,6 @@
+#!/bin/sh

+######################################################################

+# $RCSfile$ - $Revision$

+# Copyright 2012 AT&T Intellectual Property. All rights reserved.

+######################################################################

+exec sh -x ../../common/install.sh
\ No newline at end of file
diff --git a/authz-service/src/main/swm/fallback/preproc/pre_proc b/authz-service/src/main/swm/fallback/preproc/pre_proc
new file mode 100644
index 0000000..0895847
--- /dev/null
+++ b/authz-service/src/main/swm/fallback/preproc/pre_proc
@@ -0,0 +1,6 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+exit 0
\ No newline at end of file
diff --git a/authz-service/src/main/swm/initinst/postproc/post_proc b/authz-service/src/main/swm/initinst/postproc/post_proc
new file mode 100644
index 0000000..1f27b41
--- /dev/null
+++ b/authz-service/src/main/swm/initinst/postproc/post_proc
@@ -0,0 +1,6 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+exec sh -x ../../common/install.sh
diff --git a/authz-service/src/main/swm/initinst/preproc/pre_proc b/authz-service/src/main/swm/initinst/preproc/pre_proc
new file mode 100644
index 0000000..beec0a2
--- /dev/null
+++ b/authz-service/src/main/swm/initinst/preproc/pre_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+#!/bin/sh
+exit 0
\ No newline at end of file
diff --git a/authz-service/src/main/swm/install/postproc/post_proc b/authz-service/src/main/swm/install/postproc/post_proc
new file mode 100644
index 0000000..4cdbce1
--- /dev/null
+++ b/authz-service/src/main/swm/install/postproc/post_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+
+exec sh -x ../../common/install.sh
diff --git a/authz-service/src/main/swm/install/preproc/pre_proc b/authz-service/src/main/swm/install/preproc/pre_proc
new file mode 100644
index 0000000..807ebdc
--- /dev/null
+++ b/authz-service/src/main/swm/install/preproc/pre_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+
+exit 0
diff --git a/authz-service/src/main/swm/packageNotes.txt b/authz-service/src/main/swm/packageNotes.txt
new file mode 100644
index 0000000..cc8c7ee
--- /dev/null
+++ b/authz-service/src/main/swm/packageNotes.txt
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+The following two commands can be used to create and approve a SWM installation package.

+

+These steps assume:

+	1.  The component has been added in SWM

+	2.  The java6 directory resides, by itself, under the directory '${artifactId}-${version}'

+	3.  The SWM client is executed from the same directory containing '${artifactId}-${version}'

+

+

+    attuid@swmcli- --> component pkgcreate -c ${groupId}:${artifactId}:${version} -d ${artifactId}-${version}

+    attuid@swmcli- --> component pkgapprove -c ${groupId}:${artifactId}:${version}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFLur.java b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFLur.java
new file mode 100644
index 0000000..166e92a
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFLur.java
@@ -0,0 +1,66 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import static org.junit.Assert.*;

+

+import java.security.Principal;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.cadi.DirectAAFLur;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+import org.onap.aaf.cadi.Permission;

+@RunWith(PowerMockRunner.class)

+public class JU_DirectAAFLur {

+	

+public static AuthzEnv env;

+public static Question question;

+public DirectAAFLur directAAFLur;

+

+

+

+	@Before

+	public void setUp()

+	{

+	directAAFLur = new DirectAAFLur(env, question);	

+	}

+	

+	@Test

+	public void testFish()

+	{

+		

+	Principal bait = null;

+	Permission pond=null;

+	directAAFLur.fish(bait, pond);	

+	

+	assertTrue(true);

+		

+	}

+	

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFUserPass.java b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFUserPass.java
new file mode 100644
index 0000000..5a0811c
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectAAFUserPass.java
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+

+import org.onap.aaf.cadi.CredVal.Type;

+

+import static org.mockito.Mockito.*;

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.mockito.runners.MockitoJUnitRunner;

+import org.onap.aaf.authz.cadi.DirectAAFUserPass;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.dao.aaf.hl.Question;

+import org.powermock.core.classloader.annotations.PrepareForTest;

+import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+

+@RunWith(PowerMockRunner.class)

+public class JU_DirectAAFUserPass {

+	

+//public static AuthzEnv env;

+//public static Question question;

+public static String string;

+public DirectAAFUserPass directAAFUserPass;

+

+@Mock

+AuthzEnv env;

+Question question;

+String user;

+Type type; 

+byte[] pass;

+	@Before

+	public void setUp() {

+		directAAFUserPass = new DirectAAFUserPass(env, question, string);

+	}

+	

+	@Test

+	public void testvalidate(){

+

+//	Boolean bolVal =  directAAFUserPass.validate(user, type, pass);

+	//	assertEquals((bolVal==null),true);

+

+		assertTrue(true);

+		

+	}

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectCertIdentity.java b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectCertIdentity.java
new file mode 100644
index 0000000..b6f22b7
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/cadi/JU_DirectCertIdentity.java
@@ -0,0 +1,72 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.cadi;

+

+import static org.junit.Assert.*;

+

+import java.security.Principal;

+import java.security.cert.CertificateException;

+import java.security.cert.X509Certificate;

+

+import javax.servlet.http.HttpServletRequest;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.junit.runner.RunWith;

+import org.mockito.Mock;

+import org.onap.aaf.authz.cadi.DirectCertIdentity;

+import org.onap.aaf.dao.aaf.cached.CachedCertDAO;

+import org.powermock.modules.junit4.PowerMockRunner;

+

+@RunWith(PowerMockRunner.class)

+public class JU_DirectCertIdentity {

+	

+	public DirectCertIdentity directCertIdentity;

+	

+	@Before

+	public void setUp(){

+		directCertIdentity = new DirectCertIdentity();

+	}

+

+

+	@Mock

+	HttpServletRequest req;

+	X509Certificate cert;

+	byte[] _certBytes;

+	

+	@Test

+	public void testidentity(){

+		

+		try {

+		Principal p = directCertIdentity.identity(req, cert, _certBytes);

+		assertEquals(( (p) == null),true);

+			

+		} catch (CertificateException e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		//assertTrue(true);

+		

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/JU_AuthAPI.java b/authz-service/src/test/java/org/onap/aaf/authz/service/JU_AuthAPI.java
new file mode 100644
index 0000000..364869c
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/JU_AuthAPI.java
@@ -0,0 +1,75 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service;

+

+import static org.junit.Assert.*;

+

+import java.util.Properties;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.onap.aaf.authz.cadi.DirectAAFUserPass;

+import org.onap.aaf.authz.env.AuthzEnv;

+import org.onap.aaf.authz.facade.AuthzFacade_2_0;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.dao.aaf.hl.Question;

+

+public class JU_AuthAPI {

+	

+	public AuthAPI authAPI;

+	AuthzEnv env;

+	private static final String ORGANIZATION = "Organization.";

+	private static final String DOMAIN = "openecomp.org";

+

+    public Question question;

+    private AuthzFacade_2_0 facade;

+    private AuthzFacade_2_0 facade_XML;

+    private DirectAAFUserPass directAAFUserPass;

+    public Properties props;

+	@Before

+	public void setUp(){

+		try {

+			authAPI = new AuthAPI(env);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+	@Test

+	public void testStartDME2(Properties props){

+		try {

+			authAPI.startDME2(props);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		

+		//assertTrue(true);

+		

+	}

+

+

+	

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Api.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Api.java
new file mode 100644
index 0000000..08e8b4f
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Api.java
@@ -0,0 +1,59 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Api;

+

+public class JU_API_Api {

+	API_Api api_Api;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+	

+	@Before

+	public void setUp(){

+		//api_Api = new API_Api();

+	}

+

+

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit()

+	{

+		try {

+			api_Api.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		assertTrue(true);

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Approval.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Approval.java
new file mode 100644
index 0000000..e210bbc
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Approval.java
@@ -0,0 +1,61 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Approval;

+

+public class JU_API_Approval {

+	API_Approval api_Approval;

+	

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+	

+	@Before

+	public void setUp()

+	{

+		

+	}

+

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit() {

+			

+		try {

+			api_Approval.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		//assertTrue(true);

+	}

+

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Creds.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Creds.java
new file mode 100644
index 0000000..442de9e
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Creds.java
@@ -0,0 +1,73 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.cadi.DirectAAFUserPass;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Creds;

+

+import org.onap.aaf.inno.env.Env;

+

+public class JU_API_Creds {

+

+API_Creds api_Creds;

+@Mock

+AuthAPI authzAPI;

+AuthzFacade facade;

+Env env;

+DirectAAFUserPass directAAFUserPass;

+	@Before

+	public void setUp(){

+		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){		

+		try {

+			api_Creds.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testTimeSensitiveInit(){

+		

+		try {

+			api_Creds.timeSensitiveInit(env, authzAPI, facade, directAAFUserPass);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Delegate.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Delegate.java
new file mode 100644
index 0000000..79c716a
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Delegate.java
@@ -0,0 +1,55 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Delegate;

+

+public class JU_API_Delegate {

+API_Delegate api_Delegate;

+@Mock

+AuthAPI authzAPI;

+AuthzFacade facade;

+	@Before

+	public void setUp() {

+		

+		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		

+		try {

+			api_Delegate.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_History.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_History.java
new file mode 100644
index 0000000..99bc9bf
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_History.java
@@ -0,0 +1,61 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_History;

+

+public class JU_API_History {

+	API_History api_History;

+	

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+	

+	@Before

+	public void setUp(){

+		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		

+		try {

+			api_History.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		assertTrue(true);

+	}

+

+

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Mgmt.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Mgmt.java
new file mode 100644
index 0000000..d99818c
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Mgmt.java
@@ -0,0 +1,58 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Mgmt;

+

+public class JU_API_Mgmt {

+	API_Mgmt api_Mgmt;

+	

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+	

+	@Before

+	public void setUp(){

+		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		

+		try {

+			api_Mgmt.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_NS.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_NS.java
new file mode 100644
index 0000000..d2cb4e2
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_NS.java
@@ -0,0 +1,50 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_NS;

+

+public class JU_API_NS {

+	API_NS api_Ns;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		try {

+			api_Ns.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Perms.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Perms.java
new file mode 100644
index 0000000..b1b3f5b
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Perms.java
@@ -0,0 +1,67 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Perms;

+

+public class JU_API_Perms {

+	API_Perms api_Perms;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+

+	@Before

+	public void setUp(){

+		

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		try {

+			api_Perms.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testTimeSensitiveInit(){

+		try {

+			api_Perms.timeSensitiveInit(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Roles.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Roles.java
new file mode 100644
index 0000000..f52f7f6
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_Roles.java
@@ -0,0 +1,56 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_Roles;

+

+public class JU_API_Roles {

+	API_Roles api_Roles;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+	

+

+	@Before

+	public void setUp() {

+		assertTrue(true);

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		try {

+			api_Roles.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_User.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_User.java
new file mode 100644
index 0000000..2348eff
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_User.java
@@ -0,0 +1,56 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_User;

+

+public class JU_API_User {

+	API_User api_User;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+

+	@Before

+	public void setUp() {

+		//assertTrue(true);

+	}

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		try {

+			api_User.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_UserRole.java b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_UserRole.java
new file mode 100644
index 0000000..16b8ba4
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/api/JU_API_UserRole.java
@@ -0,0 +1,52 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.api;

+

+import static org.junit.Assert.*;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.mockito.Mock;

+import org.onap.aaf.authz.facade.AuthzFacade;

+import org.onap.aaf.authz.service.AuthAPI;

+import org.onap.aaf.authz.service.api.API_UserRole;

+

+public class JU_API_UserRole {

+	API_UserRole api_UserRole;

+	@Mock

+	AuthAPI authzAPI;

+	AuthzFacade facade;

+

+	

+	@SuppressWarnings("static-access")

+	@Test

+	public void testInit(){

+		try {

+			api_UserRole.init(authzAPI, facade);

+		} catch (Exception e) {

+			// TODO Auto-generated catch block

+			e.printStackTrace();

+		}

+		}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/mapper/JU_Mapper_2_0.java b/authz-service/src/test/java/org/onap/aaf/authz/service/mapper/JU_Mapper_2_0.java
new file mode 100644
index 0000000..90e1429
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/mapper/JU_Mapper_2_0.java
@@ -0,0 +1,163 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.mapper;

+

+import static org.junit.Assert.*;

+

+import org.junit.Test;

+

+public class JU_Mapper_2_0 {

+

+	@Test

+	public void test() {

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testApprovals(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testCert(){

+		assertTrue(true);

+		

+	}

+	

+	@Test

+	public void testCred(){

+		assertTrue(true);

+		

+	}

+	

+	@Test

+	public void testDelegate(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testErrorFromMessage(){

+		assertTrue(true);

+		

+	}

+	

+	@Test

+	public void testFuture(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testGetClass(){

+		assertTrue(true);

+	}

+

+	@Test

+	public void testGetExpires(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testGetMarshal(){

+		assertTrue(true);

+		

+	}

+	

+	@Test

+	public void testHistory(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testKeys(){

+		assertTrue(true);

+		

+	}

+	

+	@Test

+	public void testNewInstance(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testNs(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testNss(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testPerm(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testPermFromRPRequest(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testPermKey(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testPerms(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testRole(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testRoleFromRPRequest(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testRoles(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testUserRole(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testUserRoles(){

+		assertTrue(true);

+	}

+	

+	@Test

+	public void testUsers(){

+		assertTrue(true);

+	}

+	

+		

+	

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/test/JU_Validator.java b/authz-service/src/test/java/org/onap/aaf/authz/service/test/JU_Validator.java
new file mode 100644
index 0000000..6c5cc00
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/test/JU_Validator.java
@@ -0,0 +1,159 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.test;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import org.junit.Test;

+import org.onap.aaf.authz.service.validation.Validator;

+

+public class JU_Validator {

+

+

+	@Test

+	public void test() {

+		assertTrue(Validator.ACTION_CHARS.matcher("HowdyDoody").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("Howd?yDoody").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("_HowdyDoody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("HowdyDoody").matches());

+		assertFalse(Validator.INST_CHARS.matcher("Howd?yDoody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("_HowdyDoody").matches());

+

+		//		

+		assertTrue(Validator.ACTION_CHARS.matcher("*").matches());

+		assertTrue(Validator.INST_CHARS.matcher("*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":*:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*:*").matches());

+		

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello").matches());

+		assertFalse(Validator.INST_CHARS.matcher("hello:").matches());

+		assertFalse(Validator.INST_CHARS.matcher("hello:d").matches());

+

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello:d*:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":hello:d*d:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello:d*:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("HowdyDoody*").matches());

+		assertFalse(Validator.INST_CHARS.matcher("Howdy*Doody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("HowdyDoody*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("*HowdyDoody").matches());

+		assertFalse(Validator.INST_CHARS.matcher("*HowdyDoody").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h*h*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":h*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h:h*:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":h:h*:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:h*h:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:h*h*:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h:*:*h").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:*:*h").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":com.test.*:ns:*").matches());

+

+		

+		assertFalse(Validator.ACTION_CHARS.matcher("1234+235gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-23_5gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235g,d").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd(Version12)").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234-23 5gd").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234-235gd ").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(" 1234-235gd").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(" ").matches());

+

+		// Allow % and =   (Needed for Escaping & Base64 usages) jg 

+		assertTrue(Validator.ACTION_CHARS.matcher("1234%235g=d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:%20==").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:=%23").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:*:=%23").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*:==%20:*").matches());

+

+		// Allow / instead of :  (more natural instance expression) jg 

+		assertFalse(Validator.INST_CHARS.matcher("1234/a").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234/a").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234/*/a/").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234//a").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234/a").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("/1234/*/a/").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234//a").matches());

+

+

+		assertFalse(Validator.INST_CHARS.matcher("1234+235gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-23_5gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235g,d").matches());

+		assertTrue(Validator.INST_CHARS.matcher("m1234@shb.dd.com").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235gd(Version12)").matches());

+		assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.INST_CHARS.matcher("").matches());

+

+		

+		for( char c=0x20;c<0x7F;++c) {

+			boolean b;

+			switch(c) {

+				case '?':

+				case '|':

+				case '*':

+					continue; // test separately

+				case '~':

+				case ',':

+					b = false;

+					break;

+				default:

+					b=true;

+			}

+		}

+		

+		assertFalse(Validator.ID_CHARS.matcher("abc").matches());

+		assertFalse(Validator.ID_CHARS.matcher("").matches());

+		assertTrue(Validator.ID_CHARS.matcher("abc@att.com").matches());

+		assertTrue(Validator.ID_CHARS.matcher("ab-me@att.com").matches());

+		assertTrue(Validator.ID_CHARS.matcher("ab-me_.x@att._-com").matches());

+		

+		assertFalse(Validator.NAME_CHARS.matcher("ab-me_.x@att._-com").matches());

+		assertTrue(Validator.NAME_CHARS.matcher("ab-me").matches());

+		assertTrue(Validator.NAME_CHARS.matcher("ab-me_.xatt._-com").matches());

+

+		

+		// 7/22/2016

+		assertTrue(Validator.INST_CHARS.matcher(

+				"/!com.att.*/role/write").matches());

+		assertTrue(Validator.INST_CHARS.matcher(

+				":!com.att.*:role:write").matches());

+

+	}

+

+}

diff --git a/authz-service/src/test/java/org/onap/aaf/authz/service/validation/JU_Validator.java b/authz-service/src/test/java/org/onap/aaf/authz/service/validation/JU_Validator.java
new file mode 100644
index 0000000..1277b97
--- /dev/null
+++ b/authz-service/src/test/java/org/onap/aaf/authz/service/validation/JU_Validator.java
@@ -0,0 +1,175 @@
+/*******************************************************************************

+ * ============LICENSE_START====================================================

+ * * org.onap.aaf

+ * * ===========================================================================

+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+ * * ===========================================================================

+ * * Licensed under the Apache License, Version 2.0 (the "License");

+ * * you may not use this file except in compliance with the License.

+ * * You may obtain a copy of the License at

+ * * 

+ *  *      http://www.apache.org/licenses/LICENSE-2.0

+ * * 

+ *  * Unless required by applicable law or agreed to in writing, software

+ * * distributed under the License is distributed on an "AS IS" BASIS,

+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * * See the License for the specific language governing permissions and

+ * * limitations under the License.

+ * * ============LICENSE_END====================================================

+ * *

+ * * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+ * *

+ ******************************************************************************/

+package org.onap.aaf.authz.service.validation;

+

+import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

+import static org.junit.Assert.assertTrue;

+

+import org.junit.Before;

+import org.junit.Test;

+import org.onap.aaf.authz.cadi.DirectAAFLur.PermPermission;

+import org.onap.aaf.authz.env.AuthzTrans;

+import org.onap.aaf.authz.layer.Result;

+import org.onap.aaf.authz.org.Organization;

+import org.onap.aaf.authz.service.validation.Validator;

+import org.onap.aaf.dao.aaf.cass.CredDAO;

+import org.onap.aaf.dao.aaf.cass.DelegateDAO;

+import org.onap.aaf.dao.aaf.cass.Namespace;

+import org.onap.aaf.dao.aaf.cass.PermDAO;

+import org.onap.aaf.dao.aaf.cass.RoleDAO;

+import org.onap.aaf.dao.aaf.cass.UserRoleDAO;

+

+public class JU_Validator {

+	

+	@Before

+	public void setUp(){

+		Validator validator = new Validator();

+	}

+

+

+	@Test

+	public void test() {

+		assertTrue(Validator.ACTION_CHARS.matcher("HowdyDoody").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("Howd?yDoody").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("_HowdyDoody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("HowdyDoody").matches());

+		assertFalse(Validator.INST_CHARS.matcher("Howd?yDoody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("_HowdyDoody").matches());

+

+		//		

+		assertTrue(Validator.ACTION_CHARS.matcher("*").matches());

+		assertTrue(Validator.INST_CHARS.matcher("*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":*:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*:*").matches());

+		

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello").matches());

+		assertFalse(Validator.INST_CHARS.matcher("hello:").matches());

+		assertFalse(Validator.INST_CHARS.matcher("hello:d").matches());

+

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":hello:d*:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":hello:d*d:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":hello:d*:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("HowdyDoody*").matches());

+		assertFalse(Validator.INST_CHARS.matcher("Howdy*Doody").matches());

+		assertTrue(Validator.INST_CHARS.matcher("HowdyDoody*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("*HowdyDoody").matches());

+		assertFalse(Validator.INST_CHARS.matcher("*HowdyDoody").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h*h*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":h*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h:h*:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":h:h*:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:h*h:*").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:h*h*:*").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":h:*:*h").matches());

+		assertFalse(Validator.INST_CHARS.matcher(":h:*:*h").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":com.test.*:ns:*").matches());

+

+		

+		assertFalse(Validator.ACTION_CHARS.matcher("1234+235gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-23_5gd").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235g,d").matches());

+		assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd(Version12)").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234-23 5gd").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234-235gd ").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(" 1234-235gd").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(" ").matches());

+

+		// Allow % and =   (Needed for Escaping & Base64 usages) jg 

+		assertTrue(Validator.ACTION_CHARS.matcher("1234%235g=d").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher(":1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:%20==").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:=%23").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:*:=%23").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:*").matches());

+		assertTrue(Validator.INST_CHARS.matcher(":*:==%20:*").matches());

+

+		// Allow / instead of :  (more natural instance expression) jg 

+		assertFalse(Validator.INST_CHARS.matcher("1234/a").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234/a").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234/*/a/").matches());

+		assertTrue(Validator.INST_CHARS.matcher("/1234//a").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234/a").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("/1234/*/a/").matches());

+		assertFalse(Validator.ACTION_CHARS.matcher("1234//a").matches());

+

+

+		assertFalse(Validator.INST_CHARS.matcher("1234+235gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-23_5gd").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235g,d").matches());

+		assertTrue(Validator.INST_CHARS.matcher("m1234@shb.dd.com").matches());

+		assertTrue(Validator.INST_CHARS.matcher("1234-235gd(Version12)").matches());

+		assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());

+		assertFalse(Validator.INST_CHARS.matcher("").matches());

+

+		

+		for( char c=0x20;c<0x7F;++c) {

+			boolean b;

+			switch(c) {

+				case '?':

+				case '|':

+				case '*':

+					continue; // test separately

+				case '~':

+				case ',':

+					b = false;

+					break;

+				default:

+					b=true;

+			}

+		}

+		

+		assertFalse(Validator.ID_CHARS.matcher("abc").matches());

+		assertFalse(Validator.ID_CHARS.matcher("").matches());

+		assertTrue(Validator.ID_CHARS.matcher("abc@att.com").matches());

+		assertTrue(Validator.ID_CHARS.matcher("ab-me@att.com").matches());

+		assertTrue(Validator.ID_CHARS.matcher("ab-me_.x@att._-com").matches());

+		

+		assertFalse(Validator.NAME_CHARS.matcher("ab-me_.x@att._-com").matches());

+		assertTrue(Validator.NAME_CHARS.matcher("ab-me").matches());

+		assertTrue(Validator.NAME_CHARS.matcher("ab-me_.xatt._-com").matches());

+

+		

+		// 7/22/2016

+		assertTrue(Validator.INST_CHARS.matcher(

+				"/!com.att.*/role/write").matches());

+		assertTrue(Validator.INST_CHARS.matcher(

+				":!com.att.*:role:write").matches());

+

+	}

+

+}

diff --git a/authz-service/start.sh b/authz-service/start.sh
new file mode 100644
index 0000000..8d247c2
--- /dev/null
+++ b/authz-service/start.sh
@@ -0,0 +1,11 @@
+DIR=`pwd`
+LIB=$DIR/target/swm/package/nix/dist_files/opt/app/aaf/authz-service/2.0.15/lib
+ETC=$DIR/src/main/sample
+DME2REG=$DIR/../dme2reg
+
+CLASSPATH=$ETC
+for FILE in `find $LIB -depth 1 -name *.jar`; do
+  CLASSPATH=$CLASSPATH:$FILE
+done
+java -classpath $CLASSPATH -DDME2_EP_REGISTRY_CLASS=DME2FS -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG com.att.authz.service.AuthAPI
+
diff --git a/authz-test/TestSuite/Instructions_for_MTCs/MTC_Appr_README.txt b/authz-test/TestSuite/Instructions_for_MTCs/MTC_Appr_README.txt
new file mode 100644
index 0000000..d7ecee4
--- /dev/null
+++ b/authz-test/TestSuite/Instructions_for_MTCs/MTC_Appr_README.txt
@@ -0,0 +1,101 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+NOTE: You may find slight differences between this readme doc and your actual output in places such as <YOUR_ATTUID>, times, or other such fields that vary for each run.

+

+Do NOT replace anything inside square brackets such as [user.name] Some commands listed here use this notation, but they are set up to work by just copying & pasting the entire command.

+

+run command:		sh ./tc MTC_Appr1

+you should see:		MTC_Appr1

+					SUCCESS! [MTC_Appr1.2014-11-03_11-26-26]

+

+

+open a broswer and goto the gui for the machine you're on. For example, this is the home page on test machine zltv1492: 

+https://zltv1492.vci.att.com:8085/gui/home 

+

+click on My Approvals

+

+click the submit button at the bottom of the form with no approve or deny buttons selected

+

+you should see:     No Approvals have been sent. Try again

+

+click "Try again" link

+

+you should see:     The Approval Request page

+

+NOTE: a radio button is a (filled or unfilled) circle under approve or deny

+click the select all link for approve

+

+you should see:     all radio buttons under approve should be selected

+

+click the select all link for deny

+

+you should see:     all radio buttons under deny should be selected

+

+click the reset button at the bottom of the form

+

+you should see:     NO radio buttons should be selected

+

+Try to select both approve and deny for a single entry

+

+you should:         not be able to

+

+approve or deny entries as you like, then click submit

+

+after you have submitted all approvals, go back to My Approvals page

+

+you should see:     No Approvals to process at this time

+

+in your command line,

+run command:		aafcli ns list name com.test.appr.@[user.name].myProject

+

+NOTE: what you see here will depend on which entries you approved and denied. Included are 2 examples of what you can see:

+

+1) If you approve everything

+

+List Namespaces by Name[com.test.appr.<YOUR_ATTUID>.myProject]

+--------------------------------------------------------------------------------

+com.test.appr.<YOUR_ATTUID>.myProject

+    Administrators

+        <YOUR_ATTUID>@csp.att.com                                                      

+    Responsible Parties

+        <YOUR_ATTUID>@csp.att.com                                                      

+

+

+2) If you deny everything

+

+List Namespaces by Name[com.test.appr.<YOUR_ATTUID>.myProject]

+--------------------------------------------------------------------------------

+

+

+run command:		sh ./tc MTC_Appr2 dryrun

+you should see:     a lot of output. It's fine if you see errors for this command.

+

+run command:        aafcli ns list name com.test.appr

+you should see:     List Namespaces by Name[com.test.appr]

+--------------------------------------------------------------------------------

+

+

+run command:        aafcli ns list name com.test.appr.@[user.name]

+you should see:     List Namespaces by Name[com.test.appr.<YOUR_ATTUID>]

+--------------------------------------------------------------------------------

+

diff --git a/authz-test/TestSuite/JU_Lur2_0/10_init b/authz-test/TestSuite/JU_Lur2_0/10_init
new file mode 100644
index 0000000..a38e94b
--- /dev/null
+++ b/authz-test/TestSuite/JU_Lur2_0/10_init
@@ -0,0 +1,34 @@
+as testid@aaf.att.com:<pass>
+# JU_Lur2_0.10.0.POS List NS to prove ok
+expect 201,409
+ns create com.test.JU_Lur2_0Call @[user.name] testid@aaf.att.com
+
+# JU_Lur2_0.10.2.POS Create Role in Namespace
+role create com.test.JU_Lur2_0Call.role
+
+# JU_Lur2_0.10.10.POS Create MyInstance Perms
+perm create com.test.JU_Lur2_0Call.service myInstance write
+perm create com.test.JU_Lur2_0Call.service myInstance read
+perm create com.test.JU_Lur2_0Call.service myInstance *
+
+# JU_Lur2_0.10.11.POS Create kumquat Perms
+perm create com.test.JU_Lur2_0Call.service kumquat write
+perm create com.test.JU_Lur2_0Call.service kumquat read
+perm create com.test.JU_Lur2_0Call.service kumquat *
+perm create com.test.JU_Lur2_0Call.service kum.quat read
+
+# JU_Lur2_0.10.11.POS Create key delimited Perms
+perm create com.test.JU_Lur2_0Call.service :myCluster write
+perm create com.test.JU_Lur2_0Call.service :myCluster:myKeyspace write
+perm create com.test.JU_Lur2_0Call.service :myCluster:myKeyspace:myCF write
+perm create com.test.JU_Lur2_0Call.service :myCluster:*:myCF write
+perm create com.test.JU_Lur2_0Call.service :myCluster:myKeyspace:* write
+
+# JU_Lur2_0.10.20.POS Grant Some Perms to Role
+perm grant com.test.JU_Lur2_0Call.service myInstance * com.test.JU_Lur2_0Call.role
+perm grant com.test.JU_Lur2_0Call.service kumquat read com.test.JU_Lur2_0Call.role
+perm grant com.test.JU_Lur2_0Call.service kum.quat read com.test.JU_Lur2_0Call.role
+perm grant com.test.JU_Lur2_0Call.service :myCluster:*:myCF write com.test.JU_Lur2_0Call.role
+
+# JU_Lur2_0.30.1.POS Add User to ROle
+user role add testid@aaf.att.com com.test.JU_Lur2_0Call.role 
diff --git a/authz-test/TestSuite/JU_Lur2_0/Description b/authz-test/TestSuite/JU_Lur2_0/Description
new file mode 100644
index 0000000..748dc67
--- /dev/null
+++ b/authz-test/TestSuite/JU_Lur2_0/Description
@@ -0,0 +1,2 @@
+Load Data for CADI Test: JU_Lur2_0Call.java
+
diff --git a/authz-test/TestSuite/MTC_Appr1/00_ids b/authz-test/TestSuite/MTC_Appr1/00_ids
new file mode 100644
index 0000000..e5c040e
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set XX@NS=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/MTC_Appr1/10_init b/authz-test/TestSuite/MTC_Appr1/10_init
new file mode 100644
index 0000000..f1c61ce
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr1/10_init
@@ -0,0 +1,29 @@
+
+as testid@aaf.att.com
+
+# TC_Appr1.10.0.POS List NS to prove ok
+expect 200
+ns list name com.test.appr
+ns list name com.test.appr.@[user.name]
+
+# TC_Appr1.10.1.POS Create Personalized Namespace to add Approvals
+expect 201
+ns create com.test.appr.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Appr1.10.2.POS Create General Namespace to add Approvals
+ns create com.test.appr @[user.name] testid@aaf.att.com
+
+# TC_Appr1.10.10.POS Create Roles in Namespace
+role create com.test.appr.@[user.name].addToUserRole
+role create com.test.appr.@[user.name].grantToPerm
+role create com.test.appr.@[user.name].ungrantFromPerm
+role create com.test.appr.@[user.name].grantFirstPerm
+role create com.test.appr.@[user.name].grantSecondPerm
+
+# TC_Appr1.10.12.POS Create Permissions in Namespace
+perm create com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+perm create com.test.appr.@[user.name].grantToRole myInstance myAction
+force perm create com.test.appr.@[user.name].deleteThisPerm myInstance myAction com.test.appr.@[user.name].grantedRole
+perm create com.test.appr.@[user.name].grantTwoRoles myInstance myAction
+perm create com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+
diff --git a/authz-test/TestSuite/MTC_Appr1/15_create b/authz-test/TestSuite/MTC_Appr1/15_create
new file mode 100644
index 0000000..8791a3b
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr1/15_create
@@ -0,0 +1,40 @@
+expect 403
+as testunused@aaf.att.com
+
+# TC_Appr1.15.01.NEG Create Future and Approvals with non-admin request
+user role add @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].addToUserRole
+
+# TC_Appr1.15.02.NEG Create Approval for NS create
+ns create com.test.appr.@[user.name].myProject @[user.name]
+
+# TC_Appr1.15.03.NEG Generate Approval for granting permission to role
+perm grant com.test.appr.@[user.name].grantToRole myInstance myAction com.test.appr.@[user.name].grantToPerm
+
+# TC_Appr1.15.04.NEG Generate Approval for ungranting permission from role
+perm ungrant com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+
+# TC_Appr1.15.05.NEG Generate Approval for granting permission to role
+perm grant com.test.appr.@[user.name].grantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+
+# TC_Appr1.15.06.NEG Generate Approval for ungranting permission from role
+perm ungrant com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+
+expect 202
+# TC_Appr1.15.51.POS Create Future and Approvals with non-admin request
+set request=true user role add @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].addToUserRole
+
+# TC_Appr1.15.52.POS Create Approval for NS create
+set request=true ns create com.test.appr.@[user.name].myProject @[user.name]
+
+# TC_Appr1.15.53.POS Generate Approval for granting permission to role
+set request=true perm grant com.test.appr.@[user.name].grantToRole myInstance myAction com.test.appr.@[user.name].grantToPerm
+
+# TC_Appr1.15.54.POS Generate Approval for ungranting permission from role
+request perm ungrant com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+
+# TC_Appr1.15.55.POS Generate Approval for granting permission to role
+request perm grant com.test.appr.@[user.name].grantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+
+# TC_Appr1.15.56.POS Generate Approval for ungranting permission from role
+request perm ungrant com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+
diff --git a/authz-test/TestSuite/MTC_Appr1/Description b/authz-test/TestSuite/MTC_Appr1/Description
new file mode 100644
index 0000000..59af5e1
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user addCred :user :password
+	user delCred :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/MTC_Appr2/00_ids b/authz-test/TestSuite/MTC_Appr2/00_ids
new file mode 100644
index 0000000..e5c040e
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr2/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set XX@NS=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/MTC_Appr2/99_cleanup b/authz-test/TestSuite/MTC_Appr2/99_cleanup
new file mode 100644
index 0000000..4d6fa75
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr2/99_cleanup
@@ -0,0 +1,35 @@
+
+as testid@aaf.att.com
+
+expect 200,404
+
+# TC_Appr2.99.10.POS Delete UserRoles if exists
+user role del @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].deleteThisRole
+user role del @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].addToUserRole
+
+# TC_Appr2.10.11.POS Delete Roles if exists
+set force=true role delete com.test.appr.@[user.name].addToUserRole
+set force=true role delete com.test.appr.@[user.name].grantToPerm
+set force=true role delete com.test.appr.@[user.name].ungrantFromPerm
+role delete com.test.appr.@[user.name].grantedRole
+role delete com.test.appr.@[user.name].approvedRole
+role delete com.test.appr.@[user.name].approvedRole2
+role delete com.test.appr.@[user.name].grantFirstPerm
+role delete com.test.appr.@[user.name].grantSecondPerm
+
+# TC_Appr2.10.12.POS Delete Permissions if exists
+perm delete com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].grantedRole
+perm delete com.test.appr.@[user.name].grantToRole myInstance myAction
+perm delete com.test.appr.@[user.name].deleteThisPerm myInstance myAction com.test.appr.@[user.name].grantedRole
+perm delete com.test.appr.@[user.name].approvedPerm myInstance myAction
+perm delete com.test.appr.@[user.name].approvedPerm * *
+perm delete com.test.appr.@[user.name].approvedPerm2 myInstance myAction
+perm delete com.test.appr.@[user.name].grantTwoRoles myInstance myAction
+perm delete com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction
+
+
+# TC_Appr2.99.80.POS Delete Namespaces for TestSuite if exists
+ns delete com.test.appr.@[user.name].myProject
+set force=true ns delete com.test.appr.@[user.name] 
+set force=true ns delete com.test.appr
+
diff --git a/authz-test/TestSuite/MTC_Appr2/Description b/authz-test/TestSuite/MTC_Appr2/Description
new file mode 100644
index 0000000..59af5e1
--- /dev/null
+++ b/authz-test/TestSuite/MTC_Appr2/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user addCred :user :password
+	user delCred :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/TC_Cred1/00_ids b/authz-test/TestSuite/TC_Cred1/00_ids
new file mode 100644
index 0000000..9f6ad90
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus=boguspass
+set XX@NS=<pass>
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Cred1/10_init b/authz-test/TestSuite/TC_Cred1/10_init
new file mode 100644
index 0000000..18231c0
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/10_init
@@ -0,0 +1,36 @@
+as testid@aaf.att.com
+# TC_Cred1.10.0.POS List NS to prove ok
+expect 200
+ns list name com.test.TC_Cred1.@[user.name]
+
+# TC_Cred1.10.1.POS Create Personalized Namespace to add Credentials
+expect 201
+ns create com.test.TC_Cred1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Cred1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_Cred1.@[user.name].cred_admin testid@aaf.att.com
+role create com.test.TC_Cred1.@[user.name].pw_reset 
+
+# TC_Cred1.10.11.POS Assign roles to perms
+as XX@NS
+expect 201
+perm create com.att.aaf.password com.test reset com.test.TC_Cred1.@[user.name].pw_reset
+perm create com.att.aaf.mechid com.test create com.test.TC_Cred1.@[user.name].cred_admin 
+perm grant com.att.aaf.mechid com.att create com.test.TC_Cred1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_Cred1.10.30.POS Assign user for creating creds
+expect 201
+user cred add m99999@@[user.name].TC_Cred1.test.com password123
+set m99999@@[user.name].TC_Cred1.test.com=password123
+
+
+# TC_Cred1.10.31.POS Credential used to similate non-admin Tier1 user with reset and create permissions
+expect 201
+user role add m99999@@[user.name].TC_Cred1.test.com com.test.TC_Cred1.@[user.name].pw_reset,com.test.TC_Cred1.@[user.name].cred_admin
+
+# TC_Cred1.10.32.POS Remove create rights for testing
+expect 200
+user role del testid@aaf.att.com com.test.TC_Cred1.@[user.name].cred_admin 
+
diff --git a/authz-test/TestSuite/TC_Cred1/15_create b/authz-test/TestSuite/TC_Cred1/15_create
new file mode 100644
index 0000000..c862d98
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/15_create
@@ -0,0 +1,33 @@
+# TC_Cred1.15.1.NEG Non-Admin, no permission user cannot create mechID
+as testunused@aaf.att.com
+expect 403
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.15.3.POS Non-Admin, with create permission user can create mechID
+as m99999@@[user.name].TC_Cred1.test.com
+expect 201
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.15.10.NEG Non-Admin, no reset permission cannot reset mechID
+as testunused@aaf.att.com
+expect 403
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.15.11.POS Non-Admin, with reset permission can reset mechID
+as m99999@@[user.name].TC_Cred1.test.com:password123
+expect 200
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.15.12.POS Admin, without reset permission can reset Password
+as testid@aaf.att.com
+expect 200
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.15.15.POS Admin, without reset permission can reset mechID
+expect 200
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 1
+
+# TC_Cred1.15.20.POS Admin, delete
+expect 200
+user cred del m99990@@[user.name].TC_Cred1.test.com password123 1
+
diff --git a/authz-test/TestSuite/TC_Cred1/30_multiple_creds b/authz-test/TestSuite/TC_Cred1/30_multiple_creds
new file mode 100644
index 0000000..689225e
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/30_multiple_creds
@@ -0,0 +1,69 @@
+# TC_Cred1.30.1.NEG Multiple options available to delete
+as XX@NS
+expect 201
+user cred add m99990@@[user.name].TC_Cred1.test.com pass23Word
+
+as testid@aaf.att.com
+expect 201
+user cred add m99990@@[user.name].TC_Cred1.test.com pass23worD
+
+# TC_Cred1.30.2.POS Succeeds when we choose last option
+expect 200
+user cred del m99990@@[user.name].TC_Cred1.test.com 2
+
+# TC_Cred1.30.10.POS Add another credential
+expect 201
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.30.11.NEG Multiple options available to reset
+expect 300
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+
+# TC_Cred1.30.12.NEG Fails when we choose a bad option
+expect 406
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 0 
+
+# TC_Cred1.30.13.POS Succeeds when we choose last option
+expect 200
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 2
+
+#TC_Cred1.30.30.NEG Fails when we don't have specific property
+expect 403
+user cred extend m99990@@[user.name].TC_Cred1.test.com 
+
+#### EXTENDS behavior ####
+#TC_Cred1.30.32.POS Setup Temp Role for Extend Permission
+expect 201
+as XX@NS
+role create com.test.TC_Cred1.@[user.name].extendTemp
+
+#TC_Cred1.30.33.POS Grant Extends Permission to Role
+expect 201
+perm grant com.att.aaf.password com.att extend com.test.TC_Cred1.@[user.name].extendTemp 
+
+#TC_Cred1.30.35.POS Add current User to Temp Role for Extend Permission
+expect 201
+role user add com.test.TC_Cred1.@[user.name].extendTemp XX@NS
+
+#TC_Cred1.30.36.POS Extend Password, expecting Single Response
+expect 200
+user cred extend m99990@@[user.name].TC_Cred1.test.com 1
+
+#TC_Cred1.30.39.POS Remove Role
+expect 200
+set force=true
+role delete com.test.TC_Cred1.@[user.name].extendTemp
+
+#### MULTI CLEANUP #####
+expect 200
+role list user m99990@@[user.name].TC_Cred1.test.com 
+
+# TC_Cred1.30.80.POS Delete all entries for this cred
+expect 200
+set force=true
+user cred del m99990@@[user.name].TC_Cred1.test.com 
+
+# TC_Cred1.30.99.POS List ns shows no creds attached
+expect 200
+ns list name com.test.TC_Cred1.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Cred1/99_cleanup b/authz-test/TestSuite/TC_Cred1/99_cleanup
new file mode 100644
index 0000000..3af4174
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/99_cleanup
@@ -0,0 +1,29 @@
+as testid@aaf.att.com
+# TC_Cred1.99.1.POS Delete credentials
+expect 200,404
+force user cred del m99990@@[user.name].TC_Cred1.test.com 
+
+#TC_Cred1.99.2.POS Ensure Remove Role 
+expect 200,404
+set force=true 
+role delete com.test.TC_Cred1.@[user.name].extendTemp
+
+# TC_Cred1.99.10.POS Remove ability to create creds
+force user role del testid@aaf.att.com com.test.TC_Cred1.@[user.name].cred_admin
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Cred1.@[user.name].cred_admin
+force perm delete com.att.aaf.password com.test reset
+force perm delete com.att.aaf.mechid com.test create
+
+as testid@aaf.att.com
+force role delete com.test.TC_Cred1.@[user.name].cred_admin
+force role delete com.test.TC_Cred1.@[user.name].pw_reset
+
+# TC_Cred1.99.99.POS Delete Namespace for TestSuite 
+set force=true ns delete com.test.TC_Cred1.@[user.name] 
+
+as XX@NS
+force ns delete com.test.TC_Cred1.@[user.name]
+force ns delete com.test.TC_Cred1
+
diff --git a/authz-test/TestSuite/TC_Cred1/Description b/authz-test/TestSuite/TC_Cred1/Description
new file mode 100644
index 0000000..59af5e1
--- /dev/null
+++ b/authz-test/TestSuite/TC_Cred1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user addCred :user :password
+	user delCred :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/TC_DELG1/00_ids b/authz-test/TestSuite/TC_DELG1/00_ids
new file mode 100644
index 0000000..0f77e59
--- /dev/null
+++ b/authz-test/TestSuite/TC_DELG1/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set m99999@@[user.name].delg.test.com=password123
+set bogus@aaf.att.com=boguspass
+
+#delay 10
+set NFR=0
+
diff --git a/authz-test/TestSuite/TC_DELG1/10_init b/authz-test/TestSuite/TC_DELG1/10_init
new file mode 100644
index 0000000..558effe
--- /dev/null
+++ b/authz-test/TestSuite/TC_DELG1/10_init
@@ -0,0 +1,55 @@
+# TC_DELG1.10.1.POS Check For Existing Data
+as testid@aaf.att.com
+expect 200
+ns list name com.test.delg.@[user.name]
+
+as XX@NS
+expect 201,409
+perm create com.att.aaf.delg com.att * com.att.admin
+
+expect 404
+user list delegates delegate @[user.name]@csp.att.com
+
+as testid@aaf.att.com
+# TC_DELG1.10.2.POS Create Namespace to add IDs
+expect 201
+ns create com.test.delg.@[user.name] @[user.name] testid@aaf.att.com
+
+as XX@NS
+# TC_DELG1.10.10.POS Grant ability to change delegates
+expect 404
+force perm grant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+
+# TC_DELG1.10.11.POS Grant ability to change delegates
+expect 201
+role create com.test.delg.@[user.name].change_delg
+
+# TC_DELG1.10.12.POS Grant ability to change delegates
+expect 201
+force perm grant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+
+# TC_DELG1.10.14.POS Create user role to change delegates
+expect 201
+user role add testid@aaf.att.com com.test.delg.@[user.name].change_delg
+
+# TC_DELG1.10.15.POS Grant ability to create cred
+expect 201
+perm grant com.att.aaf.delg com.att create com.test.delg.@[user.name].change_delg
+
+as testid@aaf.att.com
+# TC_DELG1.10.30.POS Create cred that will change his own delg
+expect 201
+user cred add m99999@@[user.name].delg.test.com password123
+
+as XX@NS
+ TC_DELG1.10.31.POS ungrant ability to create cred
+expect 200
+perm ungrant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+
+as testid@aaf.att.com
+# TC_DELG1.10.99.POS Check for Data as Correct
+expect 200
+ns list name com.test.delg.@[user.name]
+
+
+
diff --git a/authz-test/TestSuite/TC_DELG1/20_create b/authz-test/TestSuite/TC_DELG1/20_create
new file mode 100644
index 0000000..2dec8bf
--- /dev/null
+++ b/authz-test/TestSuite/TC_DELG1/20_create
@@ -0,0 +1,55 @@
+# TC_DELG1.20.10.NEG Cannot create delegate with unknown user ID
+expect 404
+user delegate add aa111q@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+# TC_DELG1.20.11.NEG Cannot Create Delegate with unknown delegate
+expect 404
+user delegate add @[user.name]@csp.att.com aa111q@csp.att.com '2099-12-31 06:00'
+
+# TC_DELG1.20.20.NEG May not change user, no delegate permission
+as m99999@@[user.name].delg.test.com
+expect 403
+force user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+as testid@aaf.att.com
+# TC_DELG1.20.21.NEG Fail to Update Delegate that doesnt exist
+expect 404
+user delegate upd @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+# TC_DELG1.20.22.NEG May not create delegate for self. 
+expect 406
+user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+# TC_DELG1.20.23.POS May create delegate for self for tests by forcing.
+expect 201
+force user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+as XX@NS
+# TC_DELG1.20.30.POS Expect Delegates for User
+expect 200
+user list delegates user @[user.name]@csp.att.com
+
+as testid@aaf.att.com
+# TC_DELG1.20.35.NEG Fail Create when exists 
+expect 409
+user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+
+as XX@NS
+# TC_DELG1.20.40.POS Expect Delegates for User
+expect 200
+user list delegates user @[user.name]@csp.att.com
+
+as testid@aaf.att.com
+# TC_DELG1.20.46.POS Update Delegate with new Date
+expect 200
+user delegate upd @[user.name]@csp.att.com @[user.name]@csp.att.com '2999-01-01 06:00'
+
+as XX@NS
+# TC_DELG1.20.82.POS Expect Delegates for User
+expect 200
+user list delegates user @[user.name]@csp.att.com
+
+# TC_DELG1.20.83.POS Expect Delegate to show up in list
+expect 200
+user list delegates delegate @[user.name]@csp.att.com
+
diff --git a/authz-test/TestSuite/TC_DELG1/99_cleanup b/authz-test/TestSuite/TC_DELG1/99_cleanup
new file mode 100644
index 0000000..81dfd74
--- /dev/null
+++ b/authz-test/TestSuite/TC_DELG1/99_cleanup
@@ -0,0 +1,17 @@
+expect 200,404 
+as XX@NS
+# TC_DELG1.99.0.POS Check for Data as Correct
+ns list name com.test.delg.@[user.name]
+
+# TC_DELG1.99.10.POS Delete Delegates
+user delegate del @[user.name]@csp.att.com 
+
+# TC_DELG1.99.30.POS Delete Namespace com.att.test.id
+force ns delete com.test.delg.@[user.name]
+
+# TC_DELG1.99.98.POS Check for Delegate Data as Correct
+user list delegates user @[user.name]@csp.att.com 
+
+# TC_DELG1.99.99.POS Check for NS Data as Correct
+ns list name com.test.delg.@[user.name] 
+
diff --git a/authz-test/TestSuite/TC_DELG1/Description b/authz-test/TestSuite/TC_DELG1/Description
new file mode 100644
index 0000000..59af5e1
--- /dev/null
+++ b/authz-test/TestSuite/TC_DELG1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user addCred :user :password
+	user delCred :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/TC_Link/00_ids b/authz-test/TestSuite/TC_Link/00_ids
new file mode 100644
index 0000000..0e7a40a
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/00_ids
@@ -0,0 +1,9 @@
+expect 0
+set testid=<pass>
+set testid@aaf.att.com=<pass>
+set XX@NS=<pass>
+set testunused=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Link/05_print b/authz-test/TestSuite/TC_Link/05_print
new file mode 100644
index 0000000..62d8e25
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/05_print
@@ -0,0 +1,6 @@
+expect 200,404
+# TC_05
+ns list name com.test.TC_Link_1.@[user.name]
+ns list name com.test.TC_Link_2.@[user.name]
+perm list role com.test.TC_Link_1.@[user.name].myRole
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
diff --git a/authz-test/TestSuite/TC_Link/10_init b/authz-test/TestSuite/TC_Link/10_init
new file mode 100644
index 0000000..0f8a443
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/10_init
@@ -0,0 +1,13 @@
+expect 201
+# TC_10
+as XX@NS
+ns create com.test.TC_Link_1.@[user.name] @[user.name] XX@NS
+ns create com.test.TC_Link_2.@[user.name] @[user.name] XX@NS
+
+role create com.test.TC_Link_1.@[user.name].myRole
+
+perm create com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+
+perm grant com.test.TC_Link_2.@[user.name].myPerm myInstance myAction com.test.TC_Link_1.@[user.name].myRole
+
+
diff --git a/authz-test/TestSuite/TC_Link/15_print b/authz-test/TestSuite/TC_Link/15_print
new file mode 100644
index 0000000..ac60ddc
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/15_print
@@ -0,0 +1,6 @@
+# 15_print
+expect 200
+ns list name com.test.TC_Link_1.@[user.name]
+ns list name com.test.TC_Link_2.@[user.name]
+perm list role com.test.TC_Link_1.@[user.name].myRole
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
diff --git a/authz-test/TestSuite/TC_Link/20_del b/authz-test/TestSuite/TC_Link/20_del
new file mode 100644
index 0000000..35a01d3
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/20_del
@@ -0,0 +1,3 @@
+expect 200
+role delete com.test.TC_Link_1.@[user.name].myRole
+
diff --git a/authz-test/TestSuite/TC_Link/25_print b/authz-test/TestSuite/TC_Link/25_print
new file mode 100644
index 0000000..ac60ddc
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/25_print
@@ -0,0 +1,6 @@
+# 15_print
+expect 200
+ns list name com.test.TC_Link_1.@[user.name]
+ns list name com.test.TC_Link_2.@[user.name]
+perm list role com.test.TC_Link_1.@[user.name].myRole
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
diff --git a/authz-test/TestSuite/TC_Link/30_readd b/authz-test/TestSuite/TC_Link/30_readd
new file mode 100644
index 0000000..69bfb22
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/30_readd
@@ -0,0 +1,5 @@
+expect 201
+role create com.test.TC_Link_1.@[user.name].myRole
+
+perm grant com.test.TC_Link_2.@[user.name].myPerm myInstance myAction com.test.TC_Link_1.@[user.name].myRole
+
diff --git a/authz-test/TestSuite/TC_Link/35_print b/authz-test/TestSuite/TC_Link/35_print
new file mode 100644
index 0000000..ac60ddc
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/35_print
@@ -0,0 +1,6 @@
+# 15_print
+expect 200
+ns list name com.test.TC_Link_1.@[user.name]
+ns list name com.test.TC_Link_2.@[user.name]
+perm list role com.test.TC_Link_1.@[user.name].myRole
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
diff --git a/authz-test/TestSuite/TC_Link/99_delete b/authz-test/TestSuite/TC_Link/99_delete
new file mode 100644
index 0000000..8dfcd17
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/99_delete
@@ -0,0 +1,5 @@
+as XX@NS:<pass>
+
+expect 200,404
+force ns delete com.test.TC_Link_2.@[user.name] 
+force ns delete com.test.TC_Link_1.@[user.name]
diff --git a/authz-test/TestSuite/TC_Link/Description b/authz-test/TestSuite/TC_Link/Description
new file mode 100644
index 0000000..3abdcad
--- /dev/null
+++ b/authz-test/TestSuite/TC_Link/Description
@@ -0,0 +1,9 @@
+This Testcase Tests the essentials of Grants
+
+APIs:	
+
+
+CLI:
+   Target
+   Ancillary
+
diff --git a/authz-test/TestSuite/TC_NS1/00_ids b/authz-test/TestSuite/TC_NS1/00_ids
new file mode 100644
index 0000000..26c5db2
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/00_ids
@@ -0,0 +1,9 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus@aaf.att.com=boguspass
+
+#delay 10
+set NFR=0
+
+
diff --git a/authz-test/TestSuite/TC_NS1/01_ERR_BadData b/authz-test/TestSuite/TC_NS1/01_ERR_BadData
new file mode 100644
index 0000000..09b3b94
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/01_ERR_BadData
@@ -0,0 +1,14 @@
+
+as testid@aaf.att.com
+# TC_NS1.01.0.POS Expect Clean Namespace to start
+expect 200
+ns list name com.test.TC_NS1.@[user.name] 
+
+# TC_NS1.01.1.NEG Create Namespace with mechID as Responsible Party
+expect 403
+ns create com.test.TC_NS1.@[user.name] testunused@aaf.att.com testid@aaf.att.com,XX@NS
+
+# TC_NS1.01.2.NEG Create Namespace with Bad ID for Admin
+expect 403
+ns create com.test.TC_NS1.@[user.name] @[user.name] bogus@aaf.att.com,XX@NS
+
diff --git a/authz-test/TestSuite/TC_NS1/10_init b/authz-test/TestSuite/TC_NS1/10_init
new file mode 100644
index 0000000..b05be76
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/10_init
@@ -0,0 +1,30 @@
+
+as testid@aaf.att.com
+# TC_NS1.10.0.POS Check for Existing Data
+expect 200
+ns list name com.test.TC_NS1.@[user.name]
+
+# TC_NS1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_NS1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_NS1.10.40.POS Expect Namespace to be created
+expect 200
+ns list name com.test.TC_NS1.@[user.name] 
+
+# TC_NS1.10.41.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS1.@[user.name].admin
+
+# TC_NS1.10.42.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS1.@[user.name].owner
+
+# TC_NS1.10.43.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS1.@[user.name].access * *
+
+# TC_NS1.10.44.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS1.@[user.name].access * read
+
diff --git a/authz-test/TestSuite/TC_NS1/11_ERR_Namespace_Exists b/authz-test/TestSuite/TC_NS1/11_ERR_Namespace_Exists
new file mode 100644
index 0000000..b6aa508
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/11_ERR_Namespace_Exists
@@ -0,0 +1,4 @@
+# TC_NS1.11.1.NEG Create Namespace when exists
+expect 409
+ns create com.test.TC_NS1.@[user.name] @[user.name] testid@aaf.att.com
+
diff --git a/authz-test/TestSuite/TC_NS1/20_Commands b/authz-test/TestSuite/TC_NS1/20_Commands
new file mode 100644
index 0000000..b53750a
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/20_Commands
@@ -0,0 +1,7 @@
+# TC_NS1.20.1.NEG Too Few Args for Create 1
+expect Exception
+ns create 
+
+# TC_NS1.20.2.NEG Too Few Args for Create 2
+expect Exception
+ns create bogus
diff --git a/authz-test/TestSuite/TC_NS1/30_add_data b/authz-test/TestSuite/TC_NS1/30_add_data
new file mode 100644
index 0000000..830b965
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/30_add_data
@@ -0,0 +1,14 @@
+# TC_NS1.30.10.NEG Non-admins can't change description
+expect 403
+as testunused@aaf.att.com
+ns describe com.test.TC_NS1.@[user.name] Description for my Namespace
+
+# TC_NS1.30.11.NEG Namespace must exist to change description
+expect 404
+as testid@aaf.att.com
+ns describe com.test.TC_NS1.@[user.name].project1 Description for my project
+
+# TC_NS1.30.12.POS Admin can change description
+expect 200
+ns describe com.test.TC_NS1.@[user.name] Description for my Namespace
+
diff --git a/authz-test/TestSuite/TC_NS1/50_Admin b/authz-test/TestSuite/TC_NS1/50_Admin
new file mode 100644
index 0000000..78df9cc
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/50_Admin
@@ -0,0 +1,49 @@
+# TC_NS1.50.1.NEG Adding a Bogus ID
+expect 403
+ns admin add com.test.TC_NS1.@[user.name] bogus
+
+# TC_NS1.50.2.NEG Adding a Bogus ID, full Domain
+expect 403
+ns admin add com.test.TC_NS1.@[user.name] bogus@csp.att.com
+
+# TC_NS1.50.3.NEG Adding an OK ID, bad domain
+expect 403
+ns admin add com.test.TC_NS1.@[user.name] xz9914@bogus.test.com
+
+# TC_NS1.50.4.NEG Deleting an OK ID, but not an admin
+expect 404
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+
+sleep @[NFR]
+# TC_NS1.50.10.POS Adding an OK ID
+expect 201
+ns admin add com.test.TC_NS1.@[user.name] XX@NS
+
+# TC_NS1.50.11.POS Deleting One of Two
+expect 200
+ns admin del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+
+# TC_NS1.50.12.NEG testid@aaf.att.com no longer Admin
+expect 404
+ns admin del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+
+# TC_NS1.50.13.POS Add ID back in
+expect 201
+ns admin add com.test.TC_NS1.@[user.name] testid@aaf.att.com
+
+# TC_NS1.50.14.POS Deleting original
+expect 200
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+
+# TC_NS1.50.15.NEG Can't remove twice
+expect 404
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+
+# TC_NS1.50.20.NEG User Role Add should obey same "addAdmin" restrictions
+expect 403
+role user add com.test.TC_NS1.@[user.name].admin m88888@i.have.no.domain
+
+# TC_NS1.50.21.NEG Role User Add should obey same "addAdmin" restrictions
+expect 403
+user role add m88888@i.have.no.domain com.test.TC_NS1.@[user.name].admin 
+
diff --git a/authz-test/TestSuite/TC_NS1/60_Responsible b/authz-test/TestSuite/TC_NS1/60_Responsible
new file mode 100644
index 0000000..c6fc026
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/60_Responsible
@@ -0,0 +1,43 @@
+# TC_NS1.60.1.NEG Adding a Bogus ID
+expect 403
+ns responsible add com.test.TC_NS1.@[user.name] bogus
+
+# TC_NS1.60.2.NEG Adding a Bogus ID, full Domain
+expect 403
+ns responsible add com.test.TC_NS1.@[user.name] bogus@csp.att.com
+
+# TC_NS1.60.3.NEG Adding an OK ID, bad domain
+expect 403
+ns responsible add com.test.TC_NS1.@[user.name] xz9914@bogus.test.com
+
+# TC_NS1.60.4.NEG Deleting an OK ID, short, but not existent
+expect 404
+ns responsible del com.test.TC_NS1.@[user.name] testid
+
+# TC_NS1.60.5.NEG Deleting an OK ID, long, but not existent
+expect 404
+ns responsible del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+
+sleep @[NFR]
+# TC_NS1.60.10.POS Adding an OK ID
+# Note: mw9749 used because we must have employee as responsible
+expect 201
+ns responsible add com.test.TC_NS1.@[user.name] mw9749
+
+# TC_NS1.60.11.POS Deleting One of Two
+expect 200
+ns responsible del com.test.TC_NS1.@[user.name] mw9749
+
+# TC_NS1.60.12.NEG mw9749 no longer Admin
+expect 404
+ns responsible del com.test.TC_NS1.@[user.name] mw9749
+
+# TC_NS1.60.20.NEG User Role Add should obey same "addResponsible" restrictions
+expect 403
+role user add com.test.TC_NS1.@[user.name].owner m88888@i.have.no.domain
+
+# TC_NS1.60.21.NEG Role User Add should obey same "addResponsible" restrictions
+expect 403
+user role add m88888@i.have.no.domain com.test.TC_NS1.@[user.name].owner
+
+
diff --git a/authz-test/TestSuite/TC_NS1/80_CheckData b/authz-test/TestSuite/TC_NS1/80_CheckData
new file mode 100644
index 0000000..207c75f
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/80_CheckData
@@ -0,0 +1,15 @@
+sleep @[NFR]
+# TC_NS1.80.1.POS List Data on Empty NS
+as testid@aaf.att.com
+
+expect 200
+ns list name com.test.TC_NS1.@[user.name] 
+
+# TC_NS1.80.2.POS Add Roles to NS for Listing
+expect 201
+role create com.test.TC_NS1.@[user.name].r.A
+role create com.test.TC_NS1.@[user.name].r.B
+
+# TC_NS1.80.3.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_NS1.@[user.name] 
diff --git a/authz-test/TestSuite/TC_NS1/90_ERR_Delete b/authz-test/TestSuite/TC_NS1/90_ERR_Delete
new file mode 100644
index 0000000..324e829
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/90_ERR_Delete
@@ -0,0 +1,7 @@
+# TC_NS1.90.1.NEG Non Namespace Admin Delete Namespace
+expect 403
+as testunused@aaf.att.com
+ns delete com.test.TC_NS1.@[user.name]
+
+sleep @[NFR]
+
diff --git a/authz-test/TestSuite/TC_NS1/99_cleanup b/authz-test/TestSuite/TC_NS1/99_cleanup
new file mode 100644
index 0000000..36d5512
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/99_cleanup
@@ -0,0 +1,15 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_NS1.99.1.POS Namespace Admin can delete Namepace defined Roles
+role delete com.test.TC_NS1.@[user.name].r.A
+role delete com.test.TC_NS1.@[user.name].r.B
+
+# TC_NS1.99.2.POS Namespace Admin can delete Namespace
+ns delete com.test.TC_NS1.@[user.name]
+
+sleep @[NFR]
+
+# TC_NS1.99.99.POS Check Clean Namespace
+ns list name com.test.TC_NS1.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_NS1/Description b/authz-test/TestSuite/TC_NS1/Description
new file mode 100644
index 0000000..0cde49e
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS1/Description
@@ -0,0 +1,15 @@
+This Testcase Tests the essentials of the Namespace, and the NS Commands
+
+APIs:	POST /authz/ns
+	DELETE /authz/ns/:ns
+	GET /authz/roles/:role (where Role is NS + "*")
+
+CLI:
+   Target
+	ns create :ns :responsibleParty :admins
+	ns delete :ns
+	ns list :ns
+   Ancillary
+	role create :role
+	role list name :role.*
+
diff --git a/authz-test/TestSuite/TC_NS2/00_ids b/authz-test/TestSuite/TC_NS2/00_ids
new file mode 100644
index 0000000..450818e
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus@aaf.att.com=boguspass
+
+#delay 10
+set NFR=0
+
+
diff --git a/authz-test/TestSuite/TC_NS2/10_init b/authz-test/TestSuite/TC_NS2/10_init
new file mode 100644
index 0000000..73b2cc7
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/10_init
@@ -0,0 +1,71 @@
+
+as testid@aaf.att.com
+# TC_NS2.10.0.POS Check for Existing Data
+expect 200
+ns list name com.test.TC_NS2.@[user.name]
+
+# TC_NS2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_NS2.@[user.name] @[user.name] testid@aaf.att.com
+ns create com.test.TC_NS2.@[user.name].project @[user.name] testunused@aaf.att.com
+
+# TC_NS2.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_NS2.@[user.name].cred_admin testid@aaf.att.com
+
+as XX@NS:<pass>
+# TC_NS2.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_NS2.@[user.name].cred_admin
+
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+expect 200
+ns list name com.test.TC_NS2.@[user.name] 
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS2.@[user.name].admin
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS2.@[user.name].owner
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS2.@[user.name].access * *
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS2.@[user.name].access * read
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+expect 200
+ns list name com.test.TC_NS2.@[user.name].project
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS2.@[user.name].project.admin
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+expect 200
+perm list role com.test.TC_NS2.@[user.name].project.owner
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS2.@[user.name].project.access * *
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+expect 200
+role list perm com.test.TC_NS2.@[user.name].project.access * read
+
diff --git a/authz-test/TestSuite/TC_NS2/20_add_data b/authz-test/TestSuite/TC_NS2/20_add_data
new file mode 100644
index 0000000..ef5e11e
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/20_add_data
@@ -0,0 +1,18 @@
+as testid@aaf.att.com
+# TC_NS2.20.1.POS Create roles
+expect 201
+role create com.test.TC_NS2.@[user.name].watcher
+role create com.test.TC_NS2.@[user.name].myRole
+
+# TC_NS2.20.2.POS Create permissions
+perm create com.test.TC_NS2.@[user.name].myType myInstance myAction
+perm create com.test.TC_NS2.@[user.name].myType * *
+
+# TC_NS2.20.3.POS Create mechid
+user cred add m99990@@[user.name].TC_NS2.test.com password123
+
+as XX@NS
+# TC_NS2.20.10.POS Grant view perms to watcher role
+expect 201
+perm create com.att.aaf.ns :com.test.TC_NS2.@[user.name]:ns read com.test.TC_NS2.@[user.name].watcher
+
diff --git a/authz-test/TestSuite/TC_NS2/40_viewByName b/authz-test/TestSuite/TC_NS2/40_viewByName
new file mode 100644
index 0000000..6539acc
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/40_viewByName
@@ -0,0 +1,31 @@
+
+as testunused@aaf.att.com
+# TC_NS2.40.1.NEG Non-admin, not granted user should not view
+expect 403
+ns list name com.test.TC_NS2.@[user.name]
+
+as testid@aaf.att.com
+# Tens test user granted to permission
+# TC_NS2.40.10.POS Add user to watcher role
+expect 201
+user role add testunused@aaf.att.com com.test.TC_NS2.@[user.name].watcher
+
+as testunused@aaf.att.com
+# TC_NS2.40.11.POS Non-admin, granted user should view
+expect 200
+ns list name com.test.TC_NS2.@[user.name]
+
+as testid@aaf.att.com
+# TC_NS2.40.19.POS Remove user from watcher role
+expect 200
+user role del testunused@aaf.att.com com.test.TC_NS2.@[user.name].watcher
+
+# Thirties test admin user 
+# TC_NS2.40.20.POS Admin should be able to view
+expect 200
+ns list name com.test.TC_NS2.@[user.name]
+
+# TC_NS2.40.21.POS Admin of parent NS should be able to view
+expect 200
+ns list name com.test.TC_NS2.@[user.name].project
+
diff --git a/authz-test/TestSuite/TC_NS2/41_viewByAdmin b/authz-test/TestSuite/TC_NS2/41_viewByAdmin
new file mode 100644
index 0000000..ad15e9d
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/41_viewByAdmin
@@ -0,0 +1,20 @@
+# TC_NS2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+expect 200
+ns list admin testunused@aaf.att.com
+
+# TC_NS2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+expect 200
+ns list admin testunused@aaf.att.com
+
+# TC_NS2.41.20.POS List by User when not same as Caller, but parent owner of Namespace
+as XX@NS
+expect 200
+ns list admin testunused@aaf.att.com
+
+# TC_NS2.41.80.NEG List by User when not Caller nor associated to Namespace 
+as testunused@aaf.att.com
+expect 200
+ns list admin XX@NS
+
diff --git a/authz-test/TestSuite/TC_NS2/99_cleanup b/authz-test/TestSuite/TC_NS2/99_cleanup
new file mode 100644
index 0000000..24d16d3
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/99_cleanup
@@ -0,0 +1,27 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_NS2.99.1.POS Namespace Admin can delete Namepace defined Roles & Perms
+role delete com.test.TC_NS2.@[user.name].myRole
+role delete com.test.TC_NS2.@[user.name].watcher
+perm delete com.test.TC_NS2.@[user.name].myType myInstance myAction
+perm delete com.test.TC_NS2.@[user.name].myType * *
+user cred del m99990@@[user.name].TC_NS2.test.com
+
+as XX@NS
+force perm delete com.att.aaf.ns :com.test.TC_NS2.@[user.name]:ns read
+
+# TC_NS2.99.15.POS Remove ability to create creds
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_NS2.@[user.name].cred_admin
+
+as testid@aaf.att.com:<pass>
+force role delete com.test.TC_NS2.@[user.name].cred_admin
+
+# TC_NS2.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_NS2.@[user.name].project
+force ns delete com.test.TC_NS2.@[user.name]
+sleep @[NFR]
+
+# TC_NS2.99.99.POS Check Clean Namespace
+ns list name com.test.TC_NS2.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_NS2/Description b/authz-test/TestSuite/TC_NS2/Description
new file mode 100644
index 0000000..40f2b6c
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS2/Description
@@ -0,0 +1,7 @@
+This Testcase Tests the viewability of different ns commands
+
+APIs:	
+
+CLI:
+
+
diff --git a/authz-test/TestSuite/TC_NS3/00_ids b/authz-test/TestSuite/TC_NS3/00_ids
new file mode 100644
index 0000000..ad09d77
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set testid_1@test.com=<pass>
+set testid_2@test.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_NS3/10_init b/authz-test/TestSuite/TC_NS3/10_init
new file mode 100644
index 0000000..b13dcef
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/10_init
@@ -0,0 +1,8 @@
+as XX@NS
+expect 200
+ns list name com.test.TC_NS3.@[user.name] 
+
+# TC_NS3.10.1.POS Create Namespace with User ID
+expect 201
+ns create com.test.TC_NS3.@[user.name]_1 @[user.name] testid_1@test.com
+
diff --git a/authz-test/TestSuite/TC_NS3/20_add b/authz-test/TestSuite/TC_NS3/20_add
new file mode 100644
index 0000000..46ca091
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/20_add
@@ -0,0 +1,56 @@
+as testid_1@test.com
+expect Exception
+# TC_NS3.20.0.NEG Too short
+ns attrib
+
+# TC_NS3.20.1.NEG Wrong command
+ns attrib xyz
+
+# TC_NS3.20.2.NEG Too Short after Command
+ns attrib add
+
+# TC_NS3.20.3.NEG Too Short after Namespace
+ns attrib add com.test.TC_NS3.@[user.name]
+
+# TC_NS3.20.4.NEG Too Short after Key
+ns attrib add com.test.TC_NS3.@[user.name] TC_NS3_swm
+
+# TC_NS3.20.5.NEG No Permission
+expect 403
+ns attrib add com.test.TC_NS3.@[user.name]_1 TC_NS3_swm v1
+
+# TC_NS3.20.6.POS Create Permission to write Attrib
+expect 201
+as XX@NS
+perm create com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+
+# TC_NS3.20.6.POS Create Permission
+expect 201
+perm create com.att.aaf.attrib :com.att.*:* read com.test.TC_NS3.@[user.name]_1.admin
+
+# TC_NS3.20.10.POS Attribute added
+as testid_1@test.com
+expect 201
+ns attrib add com.test.TC_NS3.@[user.name]_1 TC_NS3_swm v1
+
+# TC_NS3.20.30.POS List NS by Attrib
+expect 200
+ns list keys TC_NS3_swm
+
+# TC_NS3.20.40.POS List NS (shows Attrib)
+ns list name com.test.TC_NS3.@[user.name]_1
+
+# TC_NS3.20.42.POS Change Attrib
+ns attrib upd com.test.TC_NS3.@[user.name]_1 TC_NS3_swm Version1
+
+# TC_NS3.20.49.POS List NS (shows new Attrib)
+ns list name com.test.TC_NS3.@[user.name]_1
+
+# TC_NS3.20.80.POS Remove write Permission
+expect 200
+perm ungrant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+
+# TC_NS3.20.83.POS Remove read Permission
+expect 200
+perm ungrant com.att.aaf.attrib :com.att.*:* read com.test.TC_NS3.@[user.name]_1.admin
+
diff --git a/authz-test/TestSuite/TC_NS3/50_delete b/authz-test/TestSuite/TC_NS3/50_delete
new file mode 100644
index 0000000..9612a1d
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/50_delete
@@ -0,0 +1,27 @@
+as testid_1@test.com
+expect Exception
+# TC_NS3.50.2.NEG Too Short after Command
+ns attrib del
+
+# TC_NS3.50.3.NEG Too Short after Namespace
+ns attrib del com.test.TC_NS3.@[user.name]
+
+# TC_NS3.50.5.NEG No Permission
+expect 403
+ns attrib del com.test.TC_NS3.@[user.name]_1 TC_NS3_swm 
+
+# TC_NS3.50.6.POS Create Permission
+as XX@NS
+expect 201
+perm grant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+
+# TC_NS3.50.7.POS Attribute added
+as testid_1@test.com
+expect 200
+ns attrib del com.test.TC_NS3.@[user.name]_1 TC_NS3_swm 
+
+# TC_NS3.50.8.POS Remove Permission
+as XX@NS
+expect 200
+perm ungrant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+
diff --git a/authz-test/TestSuite/TC_NS3/99_cleanup b/authz-test/TestSuite/TC_NS3/99_cleanup
new file mode 100644
index 0000000..104831d
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/99_cleanup
@@ -0,0 +1,14 @@
+expect 200,404
+as testid_1@test.com
+# TC_NS3.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_NS3.@[user.name]_1
+
+# TC_NS3.99.3.POS Print Namespaces
+ns list name com.test.TC_NS3.@[user.name]_1
+
+# TC_NS3.99.10.POS Remove Special Permissions
+as XX@NS
+force perm delete com.att.aaf.attrib :com.att.*:TC_NS3_swm write
+
+force perm delete com.att.aaf.attrib :com.att.*:* read
+
diff --git a/authz-test/TestSuite/TC_NS3/Description b/authz-test/TestSuite/TC_NS3/Description
new file mode 100644
index 0000000..2283774
--- /dev/null
+++ b/authz-test/TestSuite/TC_NS3/Description
@@ -0,0 +1,10 @@
+This is a TEMPLATE testcase, to make creating new Test Cases easier.
+
+APIs:	
+
+
+CLI:
+ns create
+ns delete
+as
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/00_ids b/authz-test/TestSuite/TC_NSdelete1/00_ids
new file mode 100644
index 0000000..450818e
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus@aaf.att.com=boguspass
+
+#delay 10
+set NFR=0
+
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/10_init b/authz-test/TestSuite/TC_NSdelete1/10_init
new file mode 100644
index 0000000..7be6981
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/10_init
@@ -0,0 +1,35 @@
+as testid@aaf.att.com
+# TC_NSdelete1.10.0.POS Check for Existing Data
+expect 200
+ns list name com.test.TC_NSdelete1.@[user.name].app
+ns list name com.test.force.@[user.name]
+ns list name com.@[user.name]
+
+as XX@NS
+# TC_NSdelete1.10.1.POS Create Namespaces with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_NSdelete1.@[user.name].app @[user.name] testid@aaf.att.com
+ns create com.@[user.name] @[user.name] testid@aaf.att.com
+ns create com.test.force.@[user.name] @[user.name] testid@aaf.att.com
+ns create com.test.TC_NSdelete1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_NSdelete1.10.2.POS Expect Namespace to be created
+expect 200
+ns list name com.test.TC_NSdelete1.@[user.name].app 
+ns list name com.test.TC_NSdelete1.@[user.name]
+ns list name com.@[user.name]
+ns list name com.test.force.@[user.name]
+
+# TC_NSdelete1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_NSdelete1.@[user.name].cred_admin
+
+# TC_NSdelete1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_NSdelete1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_NSdelete1.10.12.POS Assign user for creating creds
+expect 201
+user role add testid@aaf.att.com com.test.TC_NSdelete1.@[user.name].cred_admin
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/20_DeleteApp b/authz-test/TestSuite/TC_NSdelete1/20_DeleteApp
new file mode 100644
index 0000000..519e135
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/20_DeleteApp
@@ -0,0 +1,30 @@
+as testid@aaf.att.com
+# TC_NSdelete1.20.1.POS Create valid Role in my Namespace
+expect 201
+role create com.test.TC_NSdelete1.@[user.name].app.r.A
+
+# TC_NSdelete1.20.2.POS Create valid permission 
+expect 201
+perm create com.test.TC_NSdelete1.@[user.name].app.p.A myInstance myAction
+
+# TC_NSdelete1.20.3.POS Add credential to my namespace
+expect 201
+user cred add m99990@app.@[user.name].TC_NSdelete1.test.com password123
+
+# TC_NSdelete1.20.10.NEG Delete Program Should fail because of attached credential
+expect 424
+ns delete com.test.TC_NSdelete1.@[user.name].app
+
+# TC_NSdelete1.20.11.POS Delete Credential
+expect 200
+set force=true
+user cred del m99990@app.@[user.name].TC_NSdelete1.test.com
+
+# TC_NSdelete1.20.12.NEG Delete Program with role and permission attached
+expect 424
+ns delete com.test.TC_NSdelete1.@[user.name].app
+
+# TC_NSdelete1.20.20.POS Expect role and permission to move to parent ns
+expect 200
+set force=move ns list name com.test.TC_NSdelete1.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/30_DeleteCompany b/authz-test/TestSuite/TC_NSdelete1/30_DeleteCompany
new file mode 100644
index 0000000..6c69bb2
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/30_DeleteCompany
@@ -0,0 +1,42 @@
+as testid@aaf.att.com
+# TC_NSdelete1.30.1.POS Create valid Role in my Namespace
+expect 201
+role create com.@[user.name].r.A
+
+# TC_NSdelete1.30.2.NEG Delete Company with role attached
+expect 424
+ns delete com.@[user.name]
+
+# TC_NSdelete1.30.3.POS Namespace Admin can delete Namepace defined Roles
+expect 200
+role delete com.@[user.name].r.A
+
+# TC_NSdelete1.30.10.POS Create valid permission 
+expect 201
+perm create com.@[user.name].p.A myInstance myAction
+
+# TC_NSdelete1.30.11.NEG Delete Company with permission attached
+expect 424
+ns delete com.@[user.name]
+
+# TC_NSdelete1.30.12.POS Namespace Admin can delete Namepace defined Perms
+expect 200
+perm delete com.@[user.name].p.A myInstance myAction
+
+# TC_NSdelete1.30.20.POS Create valid Credential in my namespace 
+expect 201
+user cred add m99990@@[user.name].com password123
+
+# TC_NSdelete1.30.21.NEG Delete Company with credential attached
+expect 424
+ns delete com.@[user.name]
+
+# TC_NSdelete1.30.22.POS Namespace admin can remove Cred
+expect 200
+set force=true
+user cred del m99990@@[user.name].com
+
+# TC_NSdelete1.30.30.POS Delete Company with no roles or perms attached
+expect 200
+ns delete com.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/40_ForceDelete b/authz-test/TestSuite/TC_NSdelete1/40_ForceDelete
new file mode 100644
index 0000000..c4ae2bb
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/40_ForceDelete
@@ -0,0 +1,26 @@
+# TC_NSdelete1.40.1.POS Create valid Role in my Namespace

+expect 201

+role create com.test.force.@[user.name].r.A

+

+# TC_NSdelete1.40.2.POS Create valid permission in my Namespace

+expect 201

+perm create com.test.force.@[user.name].p.A myInstance myAction

+

+# TC_NSdelete1.40.3.POS Add credential to my namespace

+expect 201

+user cred add m99990@@[user.name].force.test.com password123

+

+# TC_NSdelete1.40.10.POS Delete Program in my Namespace

+expect 200

+set force=true ns delete com.test.force.@[user.name]

+

+sleep @[NFR]

+# TC_NSdelete1.40.20.NEG Role and permission should not exist

+expect 200,404

+ns list name com.test.force.@[user.name]

+

+# TC_NSdelete1.40.22.NEG Credential should not exist

+expect 404

+set force=true

+user cred del m99990@@[user.name].force.test.com

+

diff --git a/authz-test/TestSuite/TC_NSdelete1/99_cleanup b/authz-test/TestSuite/TC_NSdelete1/99_cleanup
new file mode 100644
index 0000000..cb97bc0
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/99_cleanup
@@ -0,0 +1,36 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_NSdelete1.99.1.POS Namespace Admin can delete Namepace defined Roles
+role delete com.test.TC_NSdelete1.@[user.name].app.r.A
+
+# TC_NSdelete1.99.2.POS Namespace Admin can delete Namepace defined Roles
+perm delete com.test.TC_NSdelete1.@[user.name].app.p.A myInstance myAction
+
+# TC_NSdelete1.99.3.POS Namespace Admin can remove Namepace defined Credentials
+set force=true user cred del m99990@@app.[user.name].TC_NSdelete1.test.com
+
+# TC_NSdelete1.99.10.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_NSdelete1.@[user.name].cred_admin
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_NSdelete1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+set force=true role delete com.test.TC_NSdelete1.@[user.name].cred_admin
+
+# TC_NSdelete1.99.97.POS Clean Namespace
+set force=true ns delete com.test.TC_NSdelete1.@[user.name].app
+set force=true ns delete com.test.TC_NSdelete1.@[user.name]
+set force=true ns delete com.test.force.@[user.name]
+
+# TC_NSdelete1.99.98.POS Check Clean Namespace
+ns list name com.test.TC_NSdelete1.@[user.name].app
+ns list name com.test.TC_NSdelete1.@[user.name]
+ns list name com.test.force.@[user.name]
+
+# TC_NSdelete1.99.99.POS Clean and check Company Namespace
+as XX@NS
+set force=true ns delete com.@[user.name]
+ns list name com.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_NSdelete1/Description b/authz-test/TestSuite/TC_NSdelete1/Description
new file mode 100644
index 0000000..be99e94
--- /dev/null
+++ b/authz-test/TestSuite/TC_NSdelete1/Description
@@ -0,0 +1,15 @@
+This Testcase Tests the deletion of a Namespace with attached roles and permissions
+
+APIs:	POST /authz/ns
+	DELETE /authz/ns/:ns
+	GET /authz/roles/:role (where Role is NS + "*")
+
+CLI:
+   Target
+	ns create :ns :responsibleParty :admins
+	ns delete :ns
+	ns list :ns
+   Ancillary
+	role create :role
+	role list name :role.*
+
diff --git a/authz-test/TestSuite/TC_PW1/00_ids b/authz-test/TestSuite/TC_PW1/00_ids
new file mode 100644
index 0000000..7fb0e05
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_PW1/10_init b/authz-test/TestSuite/TC_PW1/10_init
new file mode 100644
index 0000000..7614fc4
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/10_init
@@ -0,0 +1,24 @@
+
+as testid@aaf.att.com
+
+# TC_PW1.10.0.POS Validate no NS
+expect 200,404
+ns list name com.test.TC_PW1.@[user.name] 
+
+# TC_PW1.10.1.POS Create Namespace to add IDs
+expect 201
+ns create com.test.TC_PW1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_PW1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_PW1.@[user.name].cred_admin
+
+as XX@NS
+# TC_PW1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_PW1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_PW1.10.12.POS Assign user for creating creds
+expect 201
+user role add testid@aaf.att.com com.test.TC_PW1.@[user.name].cred_admin
diff --git a/authz-test/TestSuite/TC_PW1/20_length b/authz-test/TestSuite/TC_PW1/20_length
new file mode 100644
index 0000000..233683a
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/20_length
@@ -0,0 +1,10 @@
+# TC_PW1.20.1.NEG ASPR 1010 Passwords must be at least 8 characters in length
+expect 406
+user cred add m12345@TC_PW1.test.com 12
+
+# TC_PW1.20.2.NEG ASPR 1010 Passwords must be at least 8 characters in length
+user cred add m12345@TC_PW1.test.com 1
+
+# TC_PW1.20.3.NEG ASPR 1010 Passwords must be at least 8 characters in length
+user cred add m12345@TC_PW1.test.com 1234567
+
diff --git a/authz-test/TestSuite/TC_PW1/21_groups b/authz-test/TestSuite/TC_PW1/21_groups
new file mode 100644
index 0000000..0d85348
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/21_groups
@@ -0,0 +1,40 @@
+# TC_PW1.21.1.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 406
+user cred add m12345@@[user.name].TC_PW1.test.com 12345678
+
+# TC_PW1.21.2.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 406
+user cred add m12345@@[user.name].TC_PW1.test.com abcdefgh
+
+# TC_PW1.21.3.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 406
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#%^()*"
+
+# TC_PW1.21.4.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 201
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#a%^()*"
+
+sleep @[NFR]
+expect 200
+user cred del m12345@@[user.name].TC_PW1.test.com
+
+# TC_PW1.21.5.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 201
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#2%^()*"
+
+sleep @[NFR]
+expect 200
+user cred del m12345@@[user.name].TC_PW1.test.com
+
+# TC_PW1.21.6.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+expect 201
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sd"
+
+sleep @[NFR]
+expect 200
+user cred del m12345@@[user.name].TC_PW1.test.com
+
+# TC_PW1.21.10.NEG ASPR 1010 Passwords cannot be the same as the User ID
+expect 406
+user cred add m12345@@[user.name].TC_PW1.test.com m12345
+
diff --git a/authz-test/TestSuite/TC_PW1/23_commands b/authz-test/TestSuite/TC_PW1/23_commands
new file mode 100644
index 0000000..9150225
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/23_commands
@@ -0,0 +1,6 @@
+# TC_PW1.23.1.NEG Too Few Args for User Cred 1
+expect Exception
+user cred 
+
+# TC_PW1.23.2.NEG Too Few Args for User Cred add
+user cred add
diff --git a/authz-test/TestSuite/TC_PW1/30_reset b/authz-test/TestSuite/TC_PW1/30_reset
new file mode 100644
index 0000000..ac058eb
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/30_reset
@@ -0,0 +1,15 @@
+# TC_PW1.30.1.POS Create a Credential, with Temporary Time
+expect 201
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sd"
+
+# TC_PW1.30.3.NEG Credential Exists
+expect 409
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sf"
+
+# TC_PW1.30.8.POS Reset this Password
+expect 200
+user cred reset m12345@@[user.name].TC_PW1.test.com "ABC123SD" 1
+
+# TC_PW1.30.9.POS Delete a Credential
+user cred del m12345@@[user.name].TC_PW1.test.com 1
+
diff --git a/authz-test/TestSuite/TC_PW1/99_cleanup b/authz-test/TestSuite/TC_PW1/99_cleanup
new file mode 100644
index 0000000..9de2636
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/99_cleanup
@@ -0,0 +1,21 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_PW1.99.1.NEG Delete ID m12345@@[user.name].TC_PW1.test.com
+set force=true
+user cred del m12345@@[user.name].TC_PW1.test.com
+
+# TC_PW1.99.2.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_PW1.@[user.name].cred_admin
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_PW1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+role delete com.test.TC_PW1.@[user.name].cred_admin
+
+# TC_PW1.99.98.POS Delete Namespace com..test.TC_PW1
+ns delete com.test.TC_PW1.@[user.name]
+
+# TC_PW1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_PW1.@[user.name]
diff --git a/authz-test/TestSuite/TC_PW1/Description b/authz-test/TestSuite/TC_PW1/Description
new file mode 100644
index 0000000..24180f4
--- /dev/null
+++ b/authz-test/TestSuite/TC_PW1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user cred add :user :password
+	user cred del :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/TC_Perm1/00_ids b/authz-test/TestSuite/TC_Perm1/00_ids
new file mode 100644
index 0000000..0e7a40a
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/00_ids
@@ -0,0 +1,9 @@
+expect 0
+set testid=<pass>
+set testid@aaf.att.com=<pass>
+set XX@NS=<pass>
+set testunused=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Perm1/10_init b/authz-test/TestSuite/TC_Perm1/10_init
new file mode 100644
index 0000000..08a9d17
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/10_init
@@ -0,0 +1,23 @@
+# TC_Perm1.10.0.POS Validate Namespace is empty first
+as testid@aaf.att.com
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+
+# TC_Perm1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_Perm1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Perm1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_Perm1.@[user.name].cred_admin
+
+as XX@NS
+# TC_Perm1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_Perm1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_Perm1.10.12.POS Assign user for creating creds
+expect 201
+user role add XX@NS com.test.TC_Perm1.@[user.name].cred_admin
+
diff --git a/authz-test/TestSuite/TC_Perm1/20_add_data b/authz-test/TestSuite/TC_Perm1/20_add_data
new file mode 100644
index 0000000..308170f
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/20_add_data
@@ -0,0 +1,38 @@
+# TC_Perm1.20.1.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+
+# TC_Perm1.20.2.POS Add Perm 
+expect 201
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+
+# TC_Perm1.20.3.NEG Already Added Perm 
+expect 409
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+
+# TC_Perm1.20.4.POS Add Perm with non-existent Roles as well
+expect 201
+force perm create com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].r.A,com.test.TC_Perm1.@[user.name].r.B
+
+# TC_Perm1.20.8.POS Print Info for Validation
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+
+# TC_Perm1.20.9.NEG Already Added Perm with some Roles as well
+expect 409
+perm create com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].r.A,com.test.TC_Perm1.@[user.name].r.B
+
+# TC_Perm1.20.10.NEG Non-admins can't change description
+expect 403
+as testunused
+perm describe com.test.TC_Perm1.@[user.name].p.A myInstance myAction Description for A
+
+# TC_Perm1.20.11.NEG Permission must exist to change description
+expect 404
+as testid
+perm describe com.test.TC_Perm1.@[user.name].p.C myInstance myAction Description for C
+
+# TC_Perm1.20.12.POS Admin can change description
+expect 200
+perm describe com.test.TC_Perm1.@[user.name].p.A myInstance myAction Description for A
+
diff --git a/authz-test/TestSuite/TC_Perm1/22_rename b/authz-test/TestSuite/TC_Perm1/22_rename
new file mode 100644
index 0000000..e249560
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/22_rename
@@ -0,0 +1,52 @@
+# TC_Perm1.22.1.NEG Try to rename permission without changing anything

+expect 409

+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].p.B myInstance myAction

+

+# TC_Perm1.22.2.NEG Try to rename parent ns

+expect 403

+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.att.TC_Perm1.@[user.name].p.C myInstance myAction

+

+# TC_Perm1.22.10.POS View permission in original state

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+# TC_Perm1.22.11.POS Rename permission instance

+expect 200

+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].p.B yourInstance myAction

+

+# TC_Perm1.22.12.POS Verify change in permission instance

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+# TC_Perm1.22.13.POS Rename permission action

+expect 200

+perm rename com.test.TC_Perm1.@[user.name].p.B yourInstance myAction com.test.TC_Perm1.@[user.name].p.B yourInstance yourAction

+

+# TC_Perm1.22.14.POS Verify change in permission action

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+# TC_Perm1.22.15.POS Rename permission type

+expect 200

+perm rename com.test.TC_Perm1.@[user.name].p.B yourInstance yourAction com.test.TC_Perm1.@[user.name].p.yourB yourInstance yourAction

+

+# TC_Perm1.22.16.POS Verify change in permission type

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+# TC_Perm1.22.20.POS See permission is attached to this role

+expect 200

+role list role com.test.TC_Perm1.@[user.name].r.A

+

+# TC_Perm1.22.21.POS Rename permission type, instance and action

+expect 200

+perm rename com.test.TC_Perm1.@[user.name].p.yourB yourInstance yourAction com.test.TC_Perm1.@[user.name].p.B myInstance myAction

+

+# TC_Perm1.22.22.POS See permission stays attached after rename

+expect 200

+role list role com.test.TC_Perm1.@[user.name].r.A

+

+# TC_Perm1.22.23.POS Verify permission is back to original state

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

diff --git a/authz-test/TestSuite/TC_Perm1/25_grant_owned b/authz-test/TestSuite/TC_Perm1/25_grant_owned
new file mode 100644
index 0000000..3085ace
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/25_grant_owned
@@ -0,0 +1,40 @@
+# TC_Perm1.25.1.POS Create another Role in This namespace
+expect 201
+role create com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.2.POS Create another Perm in This namespace
+expect 201
+perm create com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+
+# TC_Perm1.25.3.NEG Permission must Exist to Add to Role
+expect 404
+perm grant com.test.TC_Perm1.@[user.name].p.NO myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.4.POS Grant individual new Perm to new Role
+expect 201
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.5.NEG Already Granted Perm
+expect 409
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.6.POS Print Info for Validation
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+
+# TC_Perm1.25.10.POS UnGrant individual new Perm to new Role
+expect 200
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.11.NEG Already UnGranted Perm
+expect 404
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+
+# TC_Perm1.25.20.POS Reset roles attached to permision with setTo
+expect 200
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C,com.test.TC_Perm1.@[user.name].r.A
+
+# TC_Perm1.25.21.POS Owner of permission can reset roles
+expect 200
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+
diff --git a/authz-test/TestSuite/TC_Perm1/26_grant_unowned b/authz-test/TestSuite/TC_Perm1/26_grant_unowned
new file mode 100644
index 0000000..4449624
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/26_grant_unowned
@@ -0,0 +1,175 @@
+# TC_Perm1.26.1.POS Create another Namespace, not owned by testid, one in company, one not

+as XX@NS

+expect 201

+ns create com.test2.TC_Perm1.@[user.name] @[user.name] XX@NS

+ns create com.test.TC_Perm1.@[user.name]_2 @[user.name] XX@NS

+

+# TC_Perm1.26.2.POS Create ID in other Namespace

+expect 201

+user cred add m99990@@[user.name].TC_Perm1.test2.com aRealPass7

+

+# TC_Perm1.26.3.POS Create a Role in other Namespaces, not owned by testid

+expect 201

+role create com.test2.TC_Perm1.@[user.name].r.C

+role create com.test2.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.11.NEG Grant Perm to Role in Other Namespace, when Role ID

+expect 403

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.11a.NEG Grant Perm to Role in Other Namespace, when Role ID

+expect 202

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+set request=true 

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.12.NEG Grant Perm to Role in Other Namespace, when Perm ID, but different Company

+as testid@aaf.att.com

+expect 403

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.13.NEG Fail Grant Perm to Role in Other Namespace, when Perm ID, but same Company

+as testid@aaf.att.com

+expect 404

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.14.POS Create Role

+as testid@aaf.att.com

+expect 201

+role create com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.15.POS Fail Create/Grant Perm to Role in Other Namespace, when Perm ID, but same Company

+expect 201

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.16.POS Print Info for Validation

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+# TC_Perm1.26.17.POS Grant individual new Perm to new Role

+expect 201

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.18.NEG Already Granted Perm

+expect 409

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.19.POS UnGrant Perm from Role in Other Namespace, when Perm ID

+expect 200

+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.21.NEG No Permission to Grant Perm to Role with Unrelated ID

+expect 403

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.22.NEG No Permission to Grant Perm to Role with Unrelated ID

+expect 202

+set request=true 

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.25.NEG No Permission to UnGrant with Unrelated ID

+expect 403

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.B

+

+# TC_Perm1.26.26.NEG No Permission to UnGrant with Unrelated ID

+expect 202

+set request=true 

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.B

+

+

+# TC_Perm1.26.30.POS  Add ID to Role

+as XX@NS:<pass> 

+expect 201

+ns admin add com.test2.TC_Perm1.@[user.name] m99990@@[user.name].TC_Perm1.test2.com 

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+sleep @[NFR]

+

+# TC_Perm1.26.31.NEG No Permission Grant Perm to Role if not Perm Owner

+expect 403

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.31.NEG No Permission Grant Perm to Role if not Perm Owner

+expect 202

+set request=true

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C

+

+

+# TC_Perm1.26.32.POS Grant individual new Perm to Role in Other Namespace

+expect 201

+as testid@aaf.att.com

+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.34.POS Print Info for Validation

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+

+as XX@NS

+# TC_Perm1.26.35.POS Print Info for Validation

+expect 200

+ns list name com.test2.TC_Perm1.@[user.name]  

+

+as testid@aaf.att.com

+# TC_Perm1.26.36.POS UnGrant individual new Perm to new Role

+as testid@aaf.att.com

+expect 200

+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.37.NEG Already UnGranted Perm

+expect 404

+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C

+

+# TC_Perm1.26.40.POS Reset roles attached to permision with setTo

+expect 200

+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C,com.test.TC_Perm1.@[user.name].r.A

+

+# TC_Perm1.26.41.NEG Non-owner of permission cannot reset roles

+expect 403

+as m99990@@[user.name].TC_Perm1.test2.com:aRealPass7

+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction

+

+# TC_Perm1.26.42.NEG Non-owner of permission cannot ungrant

+expect 403

+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C

+

+# TC_Perm1.26.43.NEG Non-owner of permission cannot delete

+expect 403

+perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction

+

+# TC_Perm1.26.45.POS Owner of permission can reset roles

+as testid@aaf.att.com

+expect 200

+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction

+

+as XX@NS

+# TC_Perm1.26.97.POS List the Namespaces 

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+ns list name com.test2.TC_Perm1.@[user.name]

+

+as testid@aaf.att.com

+# TC_Perm1.26.98.POS Cleanup

+expect 200

+role delete com.test.TC_Perm1.@[user.name].r.A

+role delete com.test.TC_Perm1.@[user.name].r.B

+role delete com.test.TC_Perm1.@[user.name].r.C

+role delete com.test.TC_Perm1.@[user.name]_2.r.C

+as XX@NS

+role delete com.test2.TC_Perm1.@[user.name]_2.r.C

+role delete com.test2.TC_Perm1.@[user.name].r.C

+as testid@aaf.att.com

+perm delete com.test.TC_Perm1.@[user.name].p.A myInstance myAction

+perm delete com.test.TC_Perm1.@[user.name].p.B myInstance myAction

+perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction

+force ns delete com.test.TC_Perm1.@[user.name]_2

+as XX@NS

+set force=true user cred del m99990@@[user.name].TC_Perm1.test2.com 

+ns delete com.test2.TC_Perm1.@[user.name]

+

+# TC_Perm1.26.99.POS List the Now Empty Namespaces 

+expect 200

+ns list name com.test.TC_Perm1.@[user.name]

+ns list name com.test2.TC_Perm1.@[user.name]

+

diff --git a/authz-test/TestSuite/TC_Perm1/27_grant_force b/authz-test/TestSuite/TC_Perm1/27_grant_force
new file mode 100644
index 0000000..12ee983
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/27_grant_force
@@ -0,0 +1,29 @@
+# TC_Perm1.27.1.POS Create Permission
+expect 201
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction 
+
+# TC_Perm1.27.2.POS Create Role
+expect 201
+role create com.test.TC_Perm1.@[user.name].r.A
+
+# TC_Perm1.27.10.NEG Role must Exist to Add to Role without force
+expect 404
+perm grant com.test.TC_Perm1.@[user.name].p.A myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown
+
+# TC_Perm1.27.11.POS Role is created with force
+expect 201
+force perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown
+
+# TC_Perm1.27.12.NEG Perm must Exist to Grant without force
+expect 404
+perm grant com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction com.test.TC_Perm1.@[user.name].r.A
+
+# TC_Perm1.27.13.POS Perm is created with force
+expect 201
+force perm grant com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction com.test.TC_Perm1.@[user.name].r.A
+
+# TC_Perm1.27.14.POS Role and perm are created with force
+expect 201
+force perm create com.test.TC_Perm1.@[user.name].p.unknown2 myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown2
+
+
diff --git a/authz-test/TestSuite/TC_Perm1/30_change_ns b/authz-test/TestSuite/TC_Perm1/30_change_ns
new file mode 100644
index 0000000..a92562a
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/30_change_ns
@@ -0,0 +1,14 @@
+# TC_Perm1.30.1.POS List Data on non-Empty NS
+as testid
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+
+# TC_Perm1.30.2.POS Create Sub-ns when Roles that exist
+expect 201
+ns create com.test.TC_Perm1.@[user.name].r @[user.name] testid@aaf.att.com
+
+# TC_Perm1.30.3.POS List Data on NS with sub-roles
+expect 200
+ns list name com.test.TC_Perm1.@[user.name]
+ns list name com.test.TC_Perm1.@[user.name].r
+
diff --git a/authz-test/TestSuite/TC_Perm1/99_cleanup b/authz-test/TestSuite/TC_Perm1/99_cleanup
new file mode 100644
index 0000000..222e2a4
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/99_cleanup
@@ -0,0 +1,42 @@
+as XX@NS:<pass>
+expect 200,404
+
+# TC_Perm1.99.1.POS Namespace Admin can delete Namepace defined Roles
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.B myInstance myAction
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.unknown2 myInstance myAction
+role delete com.test.TC_Perm1.@[user.name].r.A
+role delete com.test.TC_Perm1.@[user.name].r.B
+role delete com.test.TC_Perm1.@[user.name].r.C
+role delete com.test.TC_Perm1.@[user.name].r.unknown
+role delete com.test.TC_Perm1.@[user.name].r.unknown2
+role delete com.test2.TC_Perm1.@[user.name].r.C
+role delete com.test.TC_Perm1.@[user.name]_2.r.C
+role delete com.test2.TC_Perm1.@[user.name]_2.r.C
+
+# TC_Perm1.99.2.POS Remove ability to create creds
+user role del XX@NS com.test.TC_Perm1.@[user.name].cred_admin
+
+as XX@NS:<pass>
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Perm1.@[user.name].cred_admin
+
+as testid@aaf.att.com:<pass>
+role delete com.test.TC_Perm1.@[user.name].cred_admin
+
+sleep @[NFR]
+as XX@NS:<pass>
+# TC_Perm1.99.98.POS Namespace Admin can delete Namespace
+set force=true ns delete com.test2.TC_Perm1.@[user.name]
+as testid:<pass>
+force ns delete com.test.TC_Perm1.@[user.name].r
+force ns delete com.test.TC_Perm1.@[user.name]_2
+force ns delete com.test.TC_Perm1.@[user.name]
+force ns delete com.test2.TC_Perm1.@[user.name]
+
+# TC_Perm1.99.99.POS List to prove removed
+ns list name com.test.TC_Perm1.@[user.name]
+ns list name com.test.TC_Perm1.@[user.name].r
+ns list name com.test.TC_Perm1.@[user.name]_2
+ns list name com.test2.TC_Perm1.@[user.name]
diff --git a/authz-test/TestSuite/TC_Perm1/Description b/authz-test/TestSuite/TC_Perm1/Description
new file mode 100644
index 0000000..012a12b
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of the Namespace, and the NS Commands
+
+APIs:	
+
+
+
+CLI:
+   Target
+	role create :role
+	role delete 
+	ns delete :ns
+	ns list :ns
+   Ancillary
+	role create :role
+	role list name :role.*
+
diff --git a/authz-test/TestSuite/TC_Perm2/00_ids b/authz-test/TestSuite/TC_Perm2/00_ids
new file mode 100644
index 0000000..f7196fc
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Perm2/10_init b/authz-test/TestSuite/TC_Perm2/10_init
new file mode 100644
index 0000000..dbda5ed
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/10_init
@@ -0,0 +1,8 @@
+as testid@aaf.att.com
+# TC_Perm2.10.0.POS Print NS to prove ok
+expect 200
+ns list name com.test.TC_Perm2.@[user.name] 
+
+# TC_Perm2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_Perm2.@[user.name] @[user.name] testid@aaf.att.com
diff --git a/authz-test/TestSuite/TC_Perm2/20_add_data b/authz-test/TestSuite/TC_Perm2/20_add_data
new file mode 100644
index 0000000..dfcff2f
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/20_add_data
@@ -0,0 +1,44 @@
+as testid@aaf.att.com:<pass>
+# TC_Perm2.20.1.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Perm2.@[user.name]
+
+# TC_Perm2.20.10.POS Add Perms with specific Instance and Action
+expect 201
+perm create com.test.TC_Perm2.@[user.name].p.A myInstance myAction
+
+# TC_Perm2.20.11.POS Add Perms with specific Instance and Star
+expect 201
+perm create com.test.TC_Perm2.@[user.name].p.A myInstance *
+
+# TC_Perm2.20.12.POS Add Perms with Stars for Instance and Action
+expect 201
+perm create com.test.TC_Perm2.@[user.name].p.A * *
+perm create com.test.TC_Perm2.@[user.name].p.phoneCalls * spy
+
+# TC_Perm2.20.20.POS Create role 
+expect 201
+role create com.test.TC_Perm2.@[user.name].p.superUser
+role create com.test.TC_Perm2.@[user.name].p.secret
+
+# TC_Perm2.20.21.POS Grant sub-NS perms to role
+expect 201
+perm grant com.test.TC_Perm2.@[user.name].p.A myInstance myAction com.test.TC_Perm2.@[user.name].p.superUser
+perm grant com.test.TC_Perm2.@[user.name].p.A myInstance * com.test.TC_Perm2.@[user.name].p.superUser
+perm grant com.test.TC_Perm2.@[user.name].p.A * * com.test.TC_Perm2.@[user.name].p.superUser
+perm grant com.test.TC_Perm2.@[user.name].p.phoneCalls * spy com.test.TC_Perm2.@[user.name].p.secret
+
+# TC_Perm2.20.30.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Perm2.@[user.name]
+
+# TC_Perm2.20.40.POS Create role
+expect 201
+role create com.test.TC_Perm2.@[user.name].p.watcher
+
+as XX@NS
+# TC_Perm2.20.50.POS Grant view perms to watcher role
+expect 201
+perm create com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:myInstance:myAction view com.test.TC_Perm2.@[user.name].p.watcher
+perm create com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view com.test.TC_Perm2.@[user.name].p.watcher
+
diff --git a/authz-test/TestSuite/TC_Perm2/30_change_ns b/authz-test/TestSuite/TC_Perm2/30_change_ns
new file mode 100644
index 0000000..b69f9e8
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/30_change_ns
@@ -0,0 +1,14 @@
+as testid@aaf.att.com
+# TC_Perm2.30.1.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Perm2.@[user.name]
+
+# TC_Perm2.30.2.POS Create Sub-ns when Roles that exist
+expect 201
+ns create com.test.TC_Perm2.@[user.name].p @[user.name] testid@aaf.att.com
+
+# TC_Perm2.30.3.POS List Data on NS with sub-roles
+expect 200
+ns list name com.test.TC_Perm2.@[user.name]
+ns list name com.test.TC_Perm2.@[user.name].p
+
diff --git a/authz-test/TestSuite/TC_Perm2/40_viewByType b/authz-test/TestSuite/TC_Perm2/40_viewByType
new file mode 100644
index 0000000..cef41b0
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/40_viewByType
@@ -0,0 +1,82 @@
+
+as testunused@aaf.att.com
+# TC_Perm2.40.1.NEG Non-admin, not granted user should not view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+as testid@aaf.att.com
+# Tens test user granted to permission
+# TC_Perm2.40.10.POS Add user to superUser role
+expect 201
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+
+as testunused@aaf.att.com
+# TC_Perm2.40.11.POS Non-admin, granted user should view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+as testid@aaf.att.com
+# TC_Perm2.40.12.POS Ungrant perm with wildcards
+expect 200
+perm ungrant com.test.TC_Perm2.@[user.name].p.A * * com.test.TC_Perm2.@[user.name].p.superUser
+
+as testunused@aaf.att.com
+# TC_Perm2.40.13.POS Non-admin, granted user should view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+as testid@aaf.att.com
+# TC_Perm2.40.19.POS Remove user from superUser role
+expect 200
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+
+# Twenties test user granted explicit view permission
+# TC_Perm2.40.20.POS Add user to watcher role
+expect 201
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+
+as testunused@aaf.att.com
+# TC_Perm2.40.21.NEG Non-admin, granted explicit view perm user should view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+as XX@NS
+# TC_Perm2.40.22.POS Ungrant perm with wildcards
+expect 200
+perm ungrant com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view com.test.TC_Perm2.@[user.name].p.watcher
+
+as testunused@aaf.att.com
+# TC_Perm2.40.23.POS Non-admin, granted user should view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+as testid@aaf.att.com
+# TC_Perm2.40.29.POS Remove user from watcher role
+expect 200
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+
+# Thirties test admin user 
+# TC_Perm2.40.30.POS Admin should be able to view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+# TC_Perm2.40.31.POS Add new admin for sub-NS
+expect 201
+ns admin add com.test.TC_Perm2.@[user.name].p testunused@aaf.att.com
+
+# TC_Perm2.40.32.POS Remove admin from sub-NS
+expect 200
+ns admin del com.test.TC_Perm2.@[user.name].p testid@aaf.att.com
+
+# TC_Perm2.40.34.POS Admin of parent NS should be able to view
+expect 200
+perm list name com.test.TC_Perm2.@[user.name].p.A
+
+# TC_Perm2.40.80.POS Add new admin for sub-NS
+expect 201
+ns admin add com.test.TC_Perm2.@[user.name].p testid@aaf.att.com
+
+# TC_Perm2.40.81.POS Remove admin from sub-NS
+expect 200
+ns admin del com.test.TC_Perm2.@[user.name].p testunused@aaf.att.com
+
diff --git a/authz-test/TestSuite/TC_Perm2/41_viewByUser b/authz-test/TestSuite/TC_Perm2/41_viewByUser
new file mode 100644
index 0000000..51c2ecb
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/41_viewByUser
@@ -0,0 +1,34 @@
+# TC_Perm2.41.1.POS Add user to some roles with perms attached
+as testid@aaf.att.com
+expect 201
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+user role add XX@NS com.test.TC_Perm2.@[user.name].p.secret
+
+# TC_Perm2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+expect 200
+perm list user testunused@aaf.att.com
+
+# TC_NS2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+expect 200
+perm list user testunused@aaf.att.com
+
+# TC_Perm2.41.20.POS List by User when not same as Caller, but parent owner/admin of Namespace
+as XX@NS
+expect 200
+perm list user testunused@aaf.att.com
+
+# TC_Perm2.41.80.NEG List by User when not Caller nor associated to Namespace (nothing should be shown)
+as testunused@aaf.att.com
+expect 200
+perm list user XX@NS
+
+# TC_Perm2.41.99.POS Remove users from roles for later test
+as testid@aaf.att.com
+expect 200
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+user role del XX@NS com.test.TC_Perm2.@[user.name].p.secret
+
diff --git a/authz-test/TestSuite/TC_Perm2/42_viewByNS b/authz-test/TestSuite/TC_Perm2/42_viewByNS
new file mode 100644
index 0000000..69f4ed6
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/42_viewByNS
@@ -0,0 +1,10 @@
+# TC_Perm2.42.10.POS List Roles from NS when not allowed to see NS
+as testid@aaf.att.com
+expect 200
+perm list ns com.test.TC_Perm2.@[user.name].p
+
+# TC_Perm2.42.20.NEG Don't List Roles from NS when not allowed to see NS
+as testunused@aaf.att.com
+expect 403
+perm list ns com.test.TC_Perm2.@[user.name].p
+
diff --git a/authz-test/TestSuite/TC_Perm2/43_viewByRole b/authz-test/TestSuite/TC_Perm2/43_viewByRole
new file mode 100644
index 0000000..29585b4
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/43_viewByRole
@@ -0,0 +1,15 @@
+# TC_Perm2.43.10.POS List perms when allowed to see Role
+as testid@aaf.att.com
+expect 200
+perm list role com.test.TC_Perm2.@[user.name].p.superUser
+perm list role com.test.TC_Perm2.@[user.name].p.watcher
+perm list role com.test.TC_Perm2.@[user.name].p.secret
+
+# TC_Perm2.43.20.NEG Don't List perms when not allowed to see Role
+as testunused@aaf.att.com
+expect 403
+perm list role com.test.TC_Perm2.@[user.name].p.superUser
+perm list role com.test.TC_Perm2.@[user.name].p.watcher
+perm list role com.test.TC_Perm2.@[user.name].p.secret
+
+
diff --git a/authz-test/TestSuite/TC_Perm2/99_cleanup b/authz-test/TestSuite/TC_Perm2/99_cleanup
new file mode 100644
index 0000000..2d85386
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/99_cleanup
@@ -0,0 +1,24 @@
+as testid@aaf.att.com
+# TC_Perm2.99.1.POS Namespace Admin can delete Namepace defined Roles
+expect 200,404
+
+force perm delete com.test.TC_Perm2.@[user.name].p.A myInstance myAction
+force perm delete com.test.TC_Perm2.@[user.name].p.A myInstance *
+force perm delete com.test.TC_Perm2.@[user.name].p.A * *
+force perm delete com.test.TC_Perm2.@[user.name].p.phoneCalls * spy
+force role delete com.test.TC_Perm2.@[user.name].p.watcher
+force role delete com.test.TC_Perm2.@[user.name].p.superUser
+force role delete com.test.TC_Perm2.@[user.name].p.secret
+
+as XX@NS
+force perm delete com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view
+force perm delete com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:myInstance:myAction view
+
+# TC_Perm2.99.2.POS Namespace Admin can delete Namespace
+expect 200,404
+force ns delete com.test.TC_Perm2.@[user.name].p
+force ns delete com.test.TC_Perm2.@[user.name]
+
+# TC_Perm2.99.3.POS Print Namespaces
+ns list name com.test.TC_Perm2.@[user.name].p
+ns list name com.test.TC_Perm2.@[user.name]
diff --git a/authz-test/TestSuite/TC_Perm2/Description b/authz-test/TestSuite/TC_Perm2/Description
new file mode 100644
index 0000000..96cb370
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm2/Description
@@ -0,0 +1,9 @@
+This Testcase Tests the viewability of different perm commands
+
+APIs:	
+
+
+
+CLI:
+
+
diff --git a/authz-test/TestSuite/TC_Perm3/00_ids b/authz-test/TestSuite/TC_Perm3/00_ids
new file mode 100644
index 0000000..ad09d77
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set testid_1@test.com=<pass>
+set testid_2@test.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Perm3/10_init b/authz-test/TestSuite/TC_Perm3/10_init
new file mode 100644
index 0000000..f8e2ebf
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/10_init
@@ -0,0 +1,16 @@
+as XX@NS
+# TC_Perm3.10.0.POS Print NS to prove ok
+expect 200
+ns list name com.test.TC_Perm3.@[user.name] 
+
+# TC_Perm3.10.1.POS Create Namespace with User ID
+expect 201
+ns create com.test.TC_Perm3.@[user.name]_1 @[user.name] testid_1@test.com
+
+# TC_Perm3.10.2.POS Create Namespace with Different ID
+expect 201
+ns create com.test.TC_Perm3.@[user.name]_2 @[user.name] testid_2@test.com
+
+# TC_Perm3.10.3.POS Create Namespace in Different Company
+expect 201
+ns create com.att.TC_Perm3.@[user.name] @[user.name] testunused@aaf.att.com
diff --git a/authz-test/TestSuite/TC_Perm3/20_innerGrants b/authz-test/TestSuite/TC_Perm3/20_innerGrants
new file mode 100644
index 0000000..4f6482c
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/20_innerGrants
@@ -0,0 +1,29 @@
+as testid_1@test.com
+
+# TC_Perm3.20.0.POS User1 Create a Perm
+expect 201
+perm create com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction
+
+# TC_Perm3.20.5.NEG User1 should not be able to create Role in other group
+expect 403
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+
+# TC_Perm3.20.6.POS User2 should be able to create Role in own group
+as testid_2@test.com
+expect 201
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+
+# TC_Perm3.20.7.NEG User2 should not be able to grant Perm to own Role
+expect 403
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+
+# TC_Perm3.20.8.NEG User2 cannot create Role in NS 2
+as testid_2@test.com
+expect 403
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+
+# TC_Perm3.20.9.POS Role created, but can't grant... has to be testid_1
+expect 201
+as testid_1@test.com
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+
diff --git a/authz-test/TestSuite/TC_Perm3/30_outerGrants b/authz-test/TestSuite/TC_Perm3/30_outerGrants
new file mode 100644
index 0000000..ca2f7c5
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/30_outerGrants
@@ -0,0 +1,23 @@
+# TC_Perm3.30.0.POS User1 Create a Perm
+as testid_1@test.com
+expect 201
+perm create com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction
+
+# TC_Perm3.30.5.NEG User1 should not be able to create Role in other group
+expect 403
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_b
+
+# TC_Perm3.30.6.POS User2 should be able to create Role in own group
+as testunused@aaf.att.com
+expect 201
+role create com.att.TC_Perm3.@[user.name].dev.myRole_b
+
+# TC_Perm3.30.7.NEG User2 should not be able to grant Perm to own Role
+expect 403
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction com.att.TC_Perm3.@[user.name].dev.myRole_b
+
+# TC_Perm3.30.8.POS User should be able to grant cross company only Double Perm
+as testid_1@test.com
+expect 403
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction com.att.TC_Perm3.@[user.name].dev.myRole_b
+
diff --git a/authz-test/TestSuite/TC_Perm3/99_cleanup b/authz-test/TestSuite/TC_Perm3/99_cleanup
new file mode 100644
index 0000000..89b2078
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/99_cleanup
@@ -0,0 +1,22 @@
+expect 200,404
+as testid_1@test.com
+# TC_Perm3.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Perm3.@[user.name]_1
+
+# TC_Perm3.99.3.POS Print Namespaces
+ns list name com.test.TC_Perm3.@[user.name]_1
+
+as testid_2@test.com
+# TC_Perm3.99.4.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Perm3.@[user.name]_2
+
+# TC_Perm3.99.5.POS Print Namespaces
+ns list name com.test.TC_Perm3.@[user.name]_2
+
+
+as testunused@aaf.att.com
+# TC_Perm3.99.6.POS Remove Namespace from other company
+force ns delete com.att.TC_Perm3.@[user.name]
+
+# TC_Perm3.99.7.POS Print Namespace from other company
+ns list name com.att.TC_Perm3.@[user.name]
diff --git a/authz-test/TestSuite/TC_Perm3/Description b/authz-test/TestSuite/TC_Perm3/Description
new file mode 100644
index 0000000..9f572aa
--- /dev/null
+++ b/authz-test/TestSuite/TC_Perm3/Description
@@ -0,0 +1,13 @@
+This is a targeted Test Case specifically to cover Inner and Outer Granting.
+
+APIs:	
+
+
+CLI:
+ns create
+ns delete
+perm create
+perm grant
+role create
+as
+
diff --git a/authz-test/TestSuite/TC_Realm1/00_ids b/authz-test/TestSuite/TC_Realm1/00_ids
new file mode 100644
index 0000000..7fb0e05
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Realm1/10_init b/authz-test/TestSuite/TC_Realm1/10_init
new file mode 100644
index 0000000..6fee8d9
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/10_init
@@ -0,0 +1,20 @@
+
+as testid@aaf.att.com
+
+# TC_Realm1.10.0.POS Validate no NS
+expect 200,404
+ns list name com.test.TC_Realm1.@[user.name] 
+
+# TC_Realm1.10.1.POS Create Namespace to add IDs
+expect 201
+ns create com.test.TC_Realm1.@[user.name] @[user.name] testid@aaf.att.com
+
+as XX@NS
+# TC_Realm1.10.10.POS Grant ability to change delegates
+expect 201
+force perm create com.att.aaf.delg com.att create com.test.TC_Realm1.@[user.name].change_delg
+
+# TC_Realm1.10.11.POS Create user role to change delegates
+expect 201
+user role add testid@aaf.att.com com.test.TC_Realm1.@[user.name].change_delg
+
diff --git a/authz-test/TestSuite/TC_Realm1/20_ns b/authz-test/TestSuite/TC_Realm1/20_ns
new file mode 100644
index 0000000..b090d96
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/20_ns
@@ -0,0 +1,26 @@
+
+as testid@aaf.att.com
+# TC_Realm1.20.1.NEG Fail to create - default domain wrong
+expect 403
+ns create com.test.TC_Realm1.@[user.name].project1 testunused
+
+# TC_Realm1.20.2.POS Create - default domain appended
+expect 201
+ns create com.test.TC_Realm1.@[user.name].project1 @[user.name] @[user.name]
+
+# TC_Realm1.20.3.NEG Fail to create - default domain wrong
+expect 403
+ns admin add com.test.TC_Realm1.@[user.name].project1 testunused
+
+# TC_Realm1.20.4.POS Create - full domain given
+expect 201
+ns admin add com.test.TC_Realm1.@[user.name].project1 testid@aaf.att.com
+
+# TC_Realm1.20.5.POS Delete - default domain appended
+expect 200
+ns admin del com.test.TC_Realm1.@[user.name].project1 @[user.name]
+
+# TC_Realm1.20.6.POS Add admin - default domain appended
+expect 201
+ns admin add com.test.TC_Realm1.@[user.name].project1 @[user.name]
+
diff --git a/authz-test/TestSuite/TC_Realm1/30_role b/authz-test/TestSuite/TC_Realm1/30_role
new file mode 100644
index 0000000..ea99bc2
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/30_role
@@ -0,0 +1,20 @@
+# TC_Realm1.30.1.POS Create role to add to users
+expect 201
+role create com.test.TC_Realm1.@[user.name].role1
+
+# TC_Realm1.30.2.NEG Add user, but default domain wrong
+expect 403
+role user add com.test.TC_Realm1.@[user.name].role1 testunused
+
+# TC_Realm1.30.3.POS Add user, with default domain appended
+expect 201
+role user add com.test.TC_Realm1.@[user.name].role1 @[user.name]
+
+# TC_Realm1.30.10.POS Role list, with default domain added
+expect 200
+role list user testunused
+
+# TC_Realm1.30.80.POS Delete user, with default domain appended
+expect 200
+role user del com.test.TC_Realm1.@[user.name].role1 @[user.name]
+
diff --git a/authz-test/TestSuite/TC_Realm1/40_user b/authz-test/TestSuite/TC_Realm1/40_user
new file mode 100644
index 0000000..629251e
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/40_user
@@ -0,0 +1,42 @@
+# TC_Realm1.40.1.POS Create role to add to users
+expect 201
+role create com.test.TC_Realm1.@[user.name].role2
+
+# TC_Realm1.40.2.NEG Add user, but default domain wrong
+expect 403
+user role add testunused com.test.TC_Realm1.@[user.name].role2
+
+# TC_Realm1.40.3.POS Add user, with default domain appended
+expect 201
+user role add @[user.name] com.test.TC_Realm1.@[user.name].role2 
+
+# TC_Realm1.40.10.NEG Add delegate, but default domain wrong
+expect 404
+user delegate add testunused testid 2099-01-01
+
+# TC_Realm1.40.11.POS Add delegate, with default domain appended
+expect 201
+force user delegate add @[user.name] @[user.name] 2099-01-01
+
+# TC_Realm1.40.12.POS Update delegate, with default domain appended
+expect 200
+user delegate upd @[user.name] @[user.name] 2099-01-01
+
+as XX@NS
+# TC_Realm1.40.20.POS List delegate, with default domain appended
+expect 200
+user list delegates user @[user.name]
+
+# TC_Realm1.40.21.POS List delegate, with default domain appended
+expect 200
+user list delegates delegate @[user.name]
+
+as testid@aaf.att.com
+# TC_Realm1.40.80.POS Delete user, with default domain appended
+expect 200
+user role del @[user.name] com.test.TC_Realm1.@[user.name].role2 
+
+# TC_Realm1.40.81.POS Delete delegate, with default domain appended
+expect 200
+user delegate del @[user.name] 
+
diff --git a/authz-test/TestSuite/TC_Realm1/99_cleanup b/authz-test/TestSuite/TC_Realm1/99_cleanup
new file mode 100644
index 0000000..cf8c3a9
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/99_cleanup
@@ -0,0 +1,28 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_Realm1.99.1.POS Delete delgates
+user delegate del @[user.name]
+
+# TC_Realm1.99.2.POS Delete user roles
+role user del com.test.TC_Realm1.@[user.name].role1 @[user.name]
+user role del @[user.name] com.test.TC_Realm1.@[user.name].role2 
+
+# TC_Realm1.99.3.POS Delete roles
+role delete com.test.TC_Realm1.@[user.name].role1
+role delete com.test.TC_Realm1.@[user.name].role2
+
+as XX@NS
+# TC_Realm1.99.10.POS UnGrant ability to change delegates
+perm ungrant com.att.aaf.delg com.att change com.test.TC_Realm1.@[user.name].change_delg
+
+as testid@aaf.att.com
+# TC_Realm1.99.11.POS Delete role to change delegates
+set force=true role delete com.test.TC_Realm1.@[user.name].change_delg
+
+# TC_Realm1.99.98.POS Delete Namespaces
+ns delete com.test.TC_Realm1.@[user.name]
+ns delete com.test.TC_Realm1.@[user.name].project1
+
+# TC_Realm1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_Realm1.@[user.name]
diff --git a/authz-test/TestSuite/TC_Realm1/Description b/authz-test/TestSuite/TC_Realm1/Description
new file mode 100644
index 0000000..edd1685
--- /dev/null
+++ b/authz-test/TestSuite/TC_Realm1/Description
@@ -0,0 +1,2 @@
+This Testcase tests that the default domain is appended before being sent to the server
+
diff --git a/authz-test/TestSuite/TC_Role1/00_ids b/authz-test/TestSuite/TC_Role1/00_ids
new file mode 100644
index 0000000..7fb0e05
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Role1/10_init b/authz-test/TestSuite/TC_Role1/10_init
new file mode 100644
index 0000000..4af5087
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/10_init
@@ -0,0 +1,23 @@
+as testid@aaf.att.com
+
+# TC_Role1.10.0.POS Validate NS ok
+expect 200
+ns list name com.test.TC_Role1.@[user.name] 
+
+# TC_Role1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_Role1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Role1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_Role1.@[user.name].cred_admin
+
+as XX@NS
+# TC_Role1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_Role1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_Role1.10.12.POS Assign user for creating creds
+expect 201
+user role add testid@aaf.att.com com.test.TC_Role1.@[user.name].cred_admin
diff --git a/authz-test/TestSuite/TC_Role1/20_add_data b/authz-test/TestSuite/TC_Role1/20_add_data
new file mode 100644
index 0000000..43c97d9
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/20_add_data
@@ -0,0 +1,40 @@
+# TC_Role1.20.1.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Role1.@[user.name]
+
+# TC_Role1.20.2.POS Add Roles 
+expect 201
+role create com.test.TC_Role1.@[user.name].r.A
+role create com.test.TC_Role1.@[user.name].r.B
+
+# TC_Role1.20.3.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Role1.@[user.name]
+
+# TC_Role1.20.4.NEG Don't write over Role
+expect 409
+role create com.test.TC_Role1.@[user.name].r.A
+
+# TC_Role1.20.5.NEG Don't allow non-user to create
+expect 401
+as bogus
+role create com.test.TC_Role1.@[user.name].r.No
+
+# TC_Role1.20.6.NEG Don't allow non-user to create without Approval
+expect 403
+as testunused@aaf.att.com
+role create com.test.TC_Role1.@[user.name].r.No
+
+# TC_Role1.20.10.NEG Non-admins can't change description
+expect 403
+as testunused@aaf.att.com
+role describe com.test.TC_Role1.@[user.name].r.A Description A
+
+# TC_Role1.20.11.NEG Role must exist to change description
+expect 404
+as testid@aaf.att.com
+role describe com.test.TC_Role1.@[user.name].r.C Description C
+
+# TC_Role1.20.12.POS Admin can change description
+expect 200
+role describe com.test.TC_Role1.@[user.name].r.A Description A
diff --git a/authz-test/TestSuite/TC_Role1/30_change_ns b/authz-test/TestSuite/TC_Role1/30_change_ns
new file mode 100644
index 0000000..4d32f65
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/30_change_ns
@@ -0,0 +1,14 @@
+# TC_Role1.30.1.POS List Data on non-Empty NS
+as testid@aaf.att.com
+expect 200
+ns list name com.test.TC_Role1.@[user.name]
+
+# TC_Role1.30.2.POS Create Sub-ns when Roles that exist
+expect 201
+ns create com.test.TC_Role1.@[user.name].r @[user.name] testid@aaf.att.com
+
+# TC_Role1.30.3.POS List Data on NS with sub-roles
+expect 200
+ns list name com.test.TC_Role1.@[user.name]
+ns list name com.test.TC_Role1.@[user.name].r
+
diff --git a/authz-test/TestSuite/TC_Role1/40_reports b/authz-test/TestSuite/TC_Role1/40_reports
new file mode 100644
index 0000000..657d1c7
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/40_reports
@@ -0,0 +1,24 @@
+# TC_Role1.40.01.POS List Data on non-Empty NS
+expect 200
+role list role com.test.TC_Role1.@[user.name].r.A
+
+# TC_Role1.40.20.POS Create a Perm, and add to Role
+expect 201
+perm create com.test.TC_Role1.@[user.name].samplePerm1 some.long(involved).text SELECT com.test.TC_Role1.@[user.name].r.A
+
+# TC_Role1.40.25.POS List
+expect 200
+role list role com.test.TC_Role1.@[user.name].r.A
+
+# TC_Role1.40.30.POS Create a Perm 
+expect 201
+perm create com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case 
+
+# TC_Role1.40.32.POS Separately Grant Perm
+expect 201
+perm grant com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case com.test.TC_Role1.@[user.name].r.A
+
+# TC_Role1.40.35.POS List
+expect 200
+role list role com.test.TC_Role1.@[user.name].r.A
+
diff --git a/authz-test/TestSuite/TC_Role1/50_force_delete b/authz-test/TestSuite/TC_Role1/50_force_delete
new file mode 100644
index 0000000..ef334b2
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/50_force_delete
@@ -0,0 +1,28 @@
+# TC_Role1.50.1.POS Create user to attach to role

+expect 201

+user cred add m00001@@[user.name].TC_Role1.test.com password123

+

+# TC_Role1.50.2.POS Create new role

+expect 201

+role create com.test.TC_Role1.@[user.name].r.C

+

+# TC_Role1.50.3.POS Attach user to role

+expect 201

+user role add m00001@@[user.name].TC_Role1.test.com com.test.TC_Role1.@[user.name].r.C

+

+# TC_Role1.50.4.POS Create permission and attach to role

+expect 201

+perm create com.test.TC_Role1.@[user.name].p.C myInstance myAction com.test.TC_Role1.@[user.name].r.C

+

+# TC_Role1.50.20.NEG Delete role with permission and user attached should fail

+expect 424

+role delete com.test.TC_Role1.@[user.name].r.C

+

+# TC_Role1.50.21.POS Force delete role should work

+expect 200

+set force=true role delete com.test.TC_Role1.@[user.name].r.C

+

+# TC_Role1.50.30.POS List Data on non-Empty NS

+expect 200

+ns list name com.test.TC_Role1.@[user.name]

+

diff --git a/authz-test/TestSuite/TC_Role1/90_wait b/authz-test/TestSuite/TC_Role1/90_wait
new file mode 100644
index 0000000..91d890f
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/90_wait
@@ -0,0 +1,2 @@
+# Need to let DB catch up on deletes
+sleep @[NFR]
diff --git a/authz-test/TestSuite/TC_Role1/99_cleanup b/authz-test/TestSuite/TC_Role1/99_cleanup
new file mode 100644
index 0000000..63e240e
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/99_cleanup
@@ -0,0 +1,34 @@
+as testid@aaf.att.com
+expect 200,404
+
+# TC_Role1.99.05.POS Remove Permissions from "40_reports"
+set force=true perm delete com.test.TC_Role1.@[user.name].samplePerm1 some.long(involved).text SELECT
+set force=true perm delete com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case
+
+# TC_Role1.99.10.POS Namespace Admin can delete Namepace defined Roles
+force role delete com.test.TC_Role1.@[user.name].r.A
+force role delete com.test.TC_Role1.@[user.name].r.B
+force role delete com.test.TC_Role1.@[user.name].r.C
+
+# TC_Role1.99.15.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_Role1.@[user.name].cred_admin
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Role1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+role delete com.test.TC_Role1.@[user.name].cred_admin
+
+# TC_Role1.99.20.POS Namespace Admin can delete permissions and credentials
+perm delete com.test.TC_Role1.@[user.name].p.C myInstance myAction
+set force=true
+user cred del m00001@@[user.name].TC_Role1.test.com
+
+# TC_Role1.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Role1.@[user.name].r
+force ns delete com.test.TC_Role1.@[user.name]
+
+# TC_Role1.99.99.POS List to prove clean Namespaces
+ns list name com.test.TC_Role1.@[user.name].r
+ns list name com.test.TC_Role1.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Role1/Description b/authz-test/TestSuite/TC_Role1/Description
new file mode 100644
index 0000000..012a12b
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of the Namespace, and the NS Commands
+
+APIs:	
+
+
+
+CLI:
+   Target
+	role create :role
+	role delete 
+	ns delete :ns
+	ns list :ns
+   Ancillary
+	role create :role
+	role list name :role.*
+
diff --git a/authz-test/TestSuite/TC_Role2/00_ids b/authz-test/TestSuite/TC_Role2/00_ids
new file mode 100644
index 0000000..f7196fc
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Role2/10_init b/authz-test/TestSuite/TC_Role2/10_init
new file mode 100644
index 0000000..dbe7b85
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/10_init
@@ -0,0 +1,8 @@
+as testid@aaf.att.com
+# TC_Role2.10.0.POS Print NS to prove ok
+expect 200
+ns list name com.test.TC_Role2.@[user.name] 
+
+# TC_Role2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_Role2.@[user.name] @[user.name] testid@aaf.att.com
diff --git a/authz-test/TestSuite/TC_Role2/20_add_data b/authz-test/TestSuite/TC_Role2/20_add_data
new file mode 100644
index 0000000..6b85dea
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/20_add_data
@@ -0,0 +1,39 @@
+##############
+# Testing Model
+# We are making a Testing model based loosely on George Orwell's Animal Farm
+# In Animal Farm, Animals did all the work but didn't get any priviledges.
+#   In our test, the animals can't see anything but their own role, etc
+# Dogs were supervisors, and ostensibly did something, though mostly laid around
+#   In our test, they have Implicit Permissions by being Admins
+# Pigs were the Elite.  They did nothing, but watch everyone and eat the produce
+#   In our test, they have Explicit Permissions to see everything they want
+##############
+as testid@aaf.att.com:<pass>
+# TC_Role2.20.1.POS List Data on non-Empty NS
+expect 200
+ns list name com.test.TC_Role2.@[user.name]
+
+# TC_Role2.20.10.POS Create Orwellian Roles
+expect 201
+role create com.test.TC_Role2.@[user.name].r.animals 
+role create com.test.TC_Role2.@[user.name].r.dogs
+role create com.test.TC_Role2.@[user.name].r.pigs 
+
+# TC_Role2.20.20.POS Create and Grant Perms to Dog Roles
+expect 201
+perm create com.test.TC_Role2.@[user.name].r.A garbage eat com.test.TC_Role2.@[user.name].r.animals
+perm create com.test.TC_Role2.@[user.name].r.A grain eat com.test.TC_Role2.@[user.name].r.dogs
+perm create com.test.TC_Role2.@[user.name].r.A grain * com.test.TC_Role2.@[user.name].r.dogs
+perm create com.test.TC_Role2.@[user.name].r.A * * com.test.TC_Role2.@[user.name].r.dogs
+
+# TC_Role2.20.25.POS Create and Grant Animal Farm Priviledges to Pigs
+expect 201
+as XX@NS:<pass>
+perm create com.att.aaf.role com.test.TC_Role2.@[user.name].r.animals view com.test.TC_Role2.@[user.name].r.pigs
+perm create com.att.aaf.role com.test.TC_Role2.@[user.name].r.dogs view com.test.TC_Role2.@[user.name].r.pigs
+
+# TC_Role2.20.60.POS List Data on non-Empty NS
+expect 200
+as testid@aaf.att.com:<pass>
+ns list name com.test.TC_Role2.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Role2/40_viewByName b/authz-test/TestSuite/TC_Role2/40_viewByName
new file mode 100644
index 0000000..a6ec33c
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/40_viewByName
@@ -0,0 +1,45 @@
+as XX@NS
+# TC_Role2.40.1.POS List Data on Role
+expect 200
+role list role com.test.TC_Role2.@[user.name].r.animals
+role list role com.test.TC_Role2.@[user.name].r.dogs
+role list role com.test.TC_Role2.@[user.name].r.pigs
+
+# TC_Role2.40.10.POS Add testunused to animals
+expect 201
+as testid@aaf.att.com
+user role add testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.animals
+
+# TC_Role2.40.11.POS List by Name when part of role
+as testunused@aaf.att.com
+expect 200
+role list role com.test.TC_Role2.@[user.name].r.animals
+
+# TC_Role2.40.12.NEG List by Name when not part of Role
+expect 403
+role list role com.test.TC_Role2.@[user.name].r.dogs
+role list role com.test.TC_Role2.@[user.name].r.pigs
+
+
+# TC_Role2.40.30.POS Read various Roles based on being Admin in Namespace
+as testid@aaf.att.com
+expect 200
+role list role com.test.TC_Role2.@[user.name].r.animals
+role list role com.test.TC_Role2.@[user.name].r.dogs
+role list role com.test.TC_Role2.@[user.name].r.pigs
+
+# TC_Role2.40.50.POS Change testunused to Pigs
+as testid@aaf.att.com
+expect 200
+user role del testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.animals
+expect 201
+user role add testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.pigs
+
+# TC_Role2.40.51.POS Read various Roles based on having Explicit Permissions
+as testunused@aaf.att.com
+expect 403
+role list role com.test.TC_Role2.@[user.name].r.animals
+role list role com.test.TC_Role2.@[user.name].r.dogs
+expect 200
+role list role com.test.TC_Role2.@[user.name].r.pigs
+
diff --git a/authz-test/TestSuite/TC_Role2/41_viewByUser b/authz-test/TestSuite/TC_Role2/41_viewByUser
new file mode 100644
index 0000000..684d9ba
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/41_viewByUser
@@ -0,0 +1,20 @@
+# TC_Role2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+expect 200
+role list user testunused@aaf.att.com
+
+# TC_Role2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+expect 200
+role list user testunused@aaf.att.com
+
+# TC_Role2.41.20.POS List by User when not same as Caller, but parent owner of Namespace
+as XX@NS
+expect 200
+role list user testunused@aaf.att.com
+
+# TC_Role2.41.80.NEG List by User when not Caller nor associated to Namespace (nothing should be shown)
+as testunused@aaf.att.com
+expect 200
+role list user XX@NS
+
diff --git a/authz-test/TestSuite/TC_Role2/42_viewByNS b/authz-test/TestSuite/TC_Role2/42_viewByNS
new file mode 100644
index 0000000..8f18494
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/42_viewByNS
@@ -0,0 +1,10 @@
+# TC_Role2.42.10.POS List Roles from NS when not allowed to see NS
+as testid@aaf.att.com
+expect 200
+role list ns com.test.TC_Role2.@[user.name]
+
+# TC_Role2.42.20.NEG Don't List Roles from NS when not allowed to see NS
+as testunused@aaf.att.com
+expect 403
+role list ns com.test.TC_Role2.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Role2/43_viewByPerm b/authz-test/TestSuite/TC_Role2/43_viewByPerm
new file mode 100644
index 0000000..53a1e3d
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/43_viewByPerm
@@ -0,0 +1,15 @@
+# TC_Role2.43.10.POS List Roles when allowed to see Perm
+as testid@aaf.att.com
+expect 200
+role list perm com.test.TC_Role2.@[user.name].r.A grain eat
+role list perm com.test.TC_Role2.@[user.name].r.A grain *
+role list perm com.test.TC_Role2.@[user.name].r.A * *
+
+# TC_Role2.43.15.NEG Don't List Roles when not allowed to see Perm
+as testunused@aaf.att.com
+expect 403
+role list perm com.test.TC_Role2.@[user.name].r.A grain eat
+role list perm com.test.TC_Role2.@[user.name].r.A grain *
+role list perm com.test.TC_Role2.@[user.name].r.A * *
+
+
diff --git a/authz-test/TestSuite/TC_Role2/99_cleanup b/authz-test/TestSuite/TC_Role2/99_cleanup
new file mode 100644
index 0000000..df344b2
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/99_cleanup
@@ -0,0 +1,22 @@
+as XX@NS
+expect 200,404
+
+# TC_Role2.99.1.POS Delete Roles
+force role delete com.test.TC_Role2.@[user.name].r.animals
+force role delete com.test.TC_Role2.@[user.name].r.dogs
+force role delete com.test.TC_Role2.@[user.name].r.pigs
+
+# TC_Role2.99.2.POS Delete Perms
+force perm delete com.test.TC_Role2.@[user.name].r.A garbage eat
+force perm delete com.test.TC_Role2.@[user.name].r.A grain eat
+force perm delete com.test.TC_Role2.@[user.name].r.A grain *
+force perm delete com.test.TC_Role2.@[user.name].r.A * *
+force perm delete com.att.aaf.role com.test.TC_Role2.@[user.name].r.animals view
+force perm delete com.att.aaf.role com.test.TC_Role2.@[user.name].r.dogs view
+
+
+# TC_Role2.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Role2.@[user.name]
+
+# TC_Role2.99.3.POS Print Namespaces
+ns list name com.test.TC_Role2.@[user.name]
diff --git a/authz-test/TestSuite/TC_Role2/Description b/authz-test/TestSuite/TC_Role2/Description
new file mode 100644
index 0000000..ea741a8
--- /dev/null
+++ b/authz-test/TestSuite/TC_Role2/Description
@@ -0,0 +1,9 @@
+This Testcase Tests the viewability of different role commands
+
+APIs:	
+
+
+
+CLI:
+
+
diff --git a/authz-test/TestSuite/TC_UR1/00_ids b/authz-test/TestSuite/TC_UR1/00_ids
new file mode 100644
index 0000000..7fb0e05
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_UR1/10_init b/authz-test/TestSuite/TC_UR1/10_init
new file mode 100644
index 0000000..3709b5b
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/10_init
@@ -0,0 +1,31 @@
+as testid@aaf.att.com
+# TC_UR1.10.0.POS Validate no NS
+expect 200
+ns list name com.test.TC_UR1.@[user.name] 
+
+# TC_UR1.10.1.POS Create Namespace to add IDs
+expect 201
+ns create com.test.TC_UR1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Role1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_UR1.@[user.name].cred_admin
+
+as XX@NS
+# TC_Role1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_UR1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_Role1.10.12.POS Assign user for creating creds
+expect 201
+user role add testid@aaf.att.com com.test.TC_UR1.@[user.name].cred_admin
+
+# TC_UR1.10.20.POS Create two Credentials
+user cred add m00001@@[user.name].TC_UR1.test.com "abc123sd"
+user cred add m00002@@[user.name].TC_UR1.test.com "abc123sd"
+
+# TC_UR1.10.21.POS Create two Roles
+role create com.test.TC_UR1.@[user.name].r1
+role create com.test.TC_UR1.@[user.name].r2
+
diff --git a/authz-test/TestSuite/TC_UR1/23_commands b/authz-test/TestSuite/TC_UR1/23_commands
new file mode 100644
index 0000000..b534571
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/23_commands
@@ -0,0 +1,10 @@
+# TC_UR1.23.1.NEG Too Few Args for User Role 1
+expect 0
+user 
+
+# TC_UR1.23.2.NEG Too Few Args for user role
+expect Exception
+user role
+
+# TC_UR1.23.3.NEG Too Few Args for user role add
+user role add
diff --git a/authz-test/TestSuite/TC_UR1/30_userrole b/authz-test/TestSuite/TC_UR1/30_userrole
new file mode 100644
index 0000000..f4c514e
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/30_userrole
@@ -0,0 +1,53 @@
+# TC_UR1.30.10.POS Create a UserRole
+expect 201
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+
+# TC_UR1.30.11.NEG Created UserRole Exists
+expect 409
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+
+# TC_UR1.30.13.POS Delete UserRole 
+sleep @[NFR]
+expect 200
+user role del m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+
+
+# TC_UR1.30.20.POS Create multiple UserRoles
+expect 201
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+
+# TC_UR1.30.21.NEG Created UserRole Exists
+expect 409
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+
+# TC_UR1.30.23.POS Delete UserRole 
+sleep @[NFR]
+expect 200
+user role del m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+
+# TC_UR1.30.30.POS Create a Role User
+expect 201
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com 
+
+# TC_UR1.30.31.NEG Created Role User Exists
+expect 409
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com 
+
+# TC_UR1.30.33.POS Delete Role User
+sleep @[NFR]
+expect 200
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com
+
+# TC_UR1.30.40.POS Create multiple Role Users
+expect 201
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+
+# TC_UR1.30.41.NEG Created Role User Exists
+expect 409
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+
+# TC_UR1.30.43.POS Delete Role Users 
+sleep @[NFR]
+expect 200
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+
diff --git a/authz-test/TestSuite/TC_UR1/40_reset b/authz-test/TestSuite/TC_UR1/40_reset
new file mode 100644
index 0000000..66f8c17
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/40_reset
@@ -0,0 +1,40 @@
+# TC_UR1.40.10.POS Create multiple UserRoles

+expect 200

+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2

+

+# TC_UR1.40.11.POS Reset userrole for a user

+expect 200

+user role setTo m00001@@[user.name].TC_UR1.test.com

+

+# TC_UR1.40.12.NEG Create userrole where Role doesn't exist

+expect 404

+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r5

+

+# TC_UR1.40.13.NEG Create userrole where User doesn't exist

+expect 403

+user role setTo m99999@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1

+

+as testunused@aaf.att.com

+# TC_UR1.40.19.NEG User without permission tries to add userrole

+expect 403

+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1

+

+# TC_UR1.40.20.NEG User without permission tries to add userrole

+expect 403

+role user setTo com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com

+

+as testid@aaf.att.com

+# TC_UR1.40.22.POS Reset userrole for a user

+expect 200

+role user setTo com.test.TC_UR1.@[user.name].r1

+

+sleep @[NFR]

+# TC_UR1.40.23.NEG Create UserRole where Role doesn't exist

+expect 404

+role user setTo com.test.TC_UR1.@[user.name].r5 m00001@@[user.name].TC_UR1.test.com

+

+sleep @[NFR]

+# TC_UR1.40.24.NEG Create UserRole where User doesn't exist

+expect 403

+role user setTo com.test.TC_UR1.@[user.name].r1 m99999@@[user.name].TC_UR1.test.com

+

diff --git a/authz-test/TestSuite/TC_UR1/90_wait b/authz-test/TestSuite/TC_UR1/90_wait
new file mode 100644
index 0000000..91d890f
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/90_wait
@@ -0,0 +1,2 @@
+# Need to let DB catch up on deletes
+sleep @[NFR]
diff --git a/authz-test/TestSuite/TC_UR1/99_cleanup b/authz-test/TestSuite/TC_UR1/99_cleanup
new file mode 100644
index 0000000..c5e1caf
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/99_cleanup
@@ -0,0 +1,32 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_UR1.99.1.POS Remove User from Role
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com 
+role user del com.test.TC_UR1.@[user.name].r2 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com 
+role user setTo com.test.TC_UR1.@[user.name].r1
+
+# TC_UR1.99.2.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_UR1.@[user.name].cred_admin
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_UR1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+role delete com.test.TC_UR1.@[user.name].cred_admin
+
+# TC_UR1.99.3.POS Delete Creds
+set force=true
+user cred del m00001@@[user.name].TC_UR1.test.com
+set force=true
+user cred del m00002@@[user.name].TC_UR1.test.com
+
+# TC_UR1.99.4.POS Delete Roles
+set force=true role delete com.test.TC_UR1.@[user.name].r1
+set force=true role delete com.test.TC_UR1.@[user.name].r2
+
+# TC_UR1.99.5.POS Delete Namespace 
+set force=true ns delete com.test.TC_UR1.@[user.name]
+
+# TC_UR1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_UR1.@[user.name]
diff --git a/authz-test/TestSuite/TC_UR1/Description b/authz-test/TestSuite/TC_UR1/Description
new file mode 100644
index 0000000..24180f4
--- /dev/null
+++ b/authz-test/TestSuite/TC_UR1/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of User Credentials
+
+APIs:	
+   POST /auth/cred
+   PUT /auth/cred
+   DELETE /auth/cred
+
+
+CLI:
+   Target
+	user cred add :user :password
+	user cred del :user 
+   Ancillary
+	ns create 
+	ns delete 
+
diff --git a/authz-test/TestSuite/TC_User1/00_ids b/authz-test/TestSuite/TC_User1/00_ids
new file mode 100644
index 0000000..b989aa3
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/00_ids
@@ -0,0 +1,12 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set bogus@aaf.att.com=boguspass
+set m99990@@[user.name].TC_User1.test.com=password123
+set m99995@@[user.name].TC_User1.test.com=password123
+
+#delay 10
+set NFR=0
+
+
diff --git a/authz-test/TestSuite/TC_User1/10_init b/authz-test/TestSuite/TC_User1/10_init
new file mode 100644
index 0000000..0cad559
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/10_init
@@ -0,0 +1,25 @@
+
+as testid@aaf.att.com
+# TC_User1.10.0.POS Check for Existing Data
+expect 200
+ns list name com.test.TC_User1.@[user.name]
+
+# TC_User1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.test.TC_User1.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_User1.10.10.POS Create role to assign mechid perm to
+expect 201
+role create com.test.TC_User1.@[user.name].cred_admin testid@aaf.att.com
+
+as XX@NS:<pass>
+# TC_User1.10.11.POS Assign role to mechid perm
+expect 201
+perm grant com.att.aaf.mechid com.att create com.test.TC_User1.@[user.name].cred_admin
+perm grant com.att.aaf.delg com.att change com.test.TC_User1.@[user.name].cred_admin
+
+as testid@aaf.att.com
+# TC_User1.01.99.POS Expect Namespace to be created
+expect 200
+ns list name com.test.TC_User1.@[user.name] 
+
diff --git a/authz-test/TestSuite/TC_User1/20_add_data b/authz-test/TestSuite/TC_User1/20_add_data
new file mode 100644
index 0000000..9a9acec
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/20_add_data
@@ -0,0 +1,26 @@
+as testid@aaf.att.com
+# TC_User1.20.1.POS Create roles
+expect 201
+role create com.test.TC_User1.@[user.name].manager
+role create com.test.TC_User1.@[user.name].worker
+
+# TC_User1.20.2.POS Create permissions
+perm create com.test.TC_User1.@[user.name].supplies * move com.test.TC_User1.@[user.name].worker
+perm create com.test.TC_User1.@[user.name].supplies * stock com.test.TC_User1.@[user.name].worker
+perm create com.test.TC_User1.@[user.name].schedule worker create com.test.TC_User1.@[user.name].manager
+perm create com.test.TC_User1.@[user.name].worker * annoy com.test.TC_User1.@[user.name].manager
+
+# TC_User1.20.3.POS Create mechid
+user cred add m99990@@[user.name].TC_User1.test.com password123
+user cred add m99995@@[user.name].TC_User1.test.com password123
+
+as XX@NS
+# TC_User1.20.10.POS Add users to roles
+expect 201
+user role add @[user.name] com.test.TC_User1.@[user.name].manager
+user role add m99990@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+
+# TC_User1.20.20.POS Add Delegate
+as XX@NS
+# TC_User1.20.20.POS Create delegates
+force user delegate add @[user.name] @[user.name]
diff --git a/authz-test/TestSuite/TC_User1/40_viewByRole b/authz-test/TestSuite/TC_User1/40_viewByRole
new file mode 100644
index 0000000..824f01e
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/40_viewByRole
@@ -0,0 +1,23 @@
+
+# TC_User1.40.1.NEG Non-admin, user not in role should not view
+expect 403
+as testunused@aaf.att.com
+user list role com.test.TC_User1.@[user.name].manager
+user list role com.test.TC_User1.@[user.name].worker
+
+as m99990@@[user.name].TC_User1.test.com
+# TC_User1.40.2.NEG Non-admin, user in role should not view
+expect 403
+user list role com.test.TC_User1.@[user.name].manager
+
+sleep @[NFR]
+# TC_User1.40.3.POS Non-admin, user in role can view himself
+expect 200
+user list role com.test.TC_User1.@[user.name].worker
+
+as testid@aaf.att.com
+# TC_User1.40.10.POS admin should view
+expect 200
+user list role com.test.TC_User1.@[user.name].manager
+user list role com.test.TC_User1.@[user.name].worker
+
diff --git a/authz-test/TestSuite/TC_User1/41_viewByPerm b/authz-test/TestSuite/TC_User1/41_viewByPerm
new file mode 100644
index 0000000..6813cb1
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/41_viewByPerm
@@ -0,0 +1,29 @@
+as testunused@aaf.att.com
+# TC_User1.41.1.NEG Non-admin, user not in perm should not view
+expect 200
+user list perm com.test.TC_User1.@[user.name].supplies * move
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+
+as m99990@@[user.name].TC_User1.test.com
+# TC_User1.41.2.POS Non-admin, user in perm can view himself
+expect 200
+user list perm com.test.TC_User1.@[user.name].supplies * move
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+
+as m99990@@[user.name].TC_User1.test.com
+# TC_User1.41.3.NEG Non-admin, user in perm should not view
+expect 200
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+
+as testid@aaf.att.com
+# TC_User1.41.10.POS admin should view
+expect 200
+user list perm com.test.TC_User1.@[user.name].supplies * move
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+
+
diff --git a/authz-test/TestSuite/TC_User1/42_viewByDelegates b/authz-test/TestSuite/TC_User1/42_viewByDelegates
new file mode 100644
index 0000000..7d16cb3
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/42_viewByDelegates
@@ -0,0 +1,12 @@
+as testunused@aaf.att.com
+# TC_User1.42.1.NEG Unrelated user can't view delegates
+expect 403
+user list delegates user m99990@@[user.name].TC_User1.test.com
+user list delegates delegate m99995@@[user.name].TC_User1.test.com
+
+as XX@NS
+# TC_User1.42.10.POS Admin of domain NS can view
+expect 200
+user list delegates user @[user.name]
+user list delegates delegate @[user.name]
+
diff --git a/authz-test/TestSuite/TC_User1/43_viewsExplicitiPerm b/authz-test/TestSuite/TC_User1/43_viewsExplicitiPerm
new file mode 100644
index 0000000..8f4ffd0
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/43_viewsExplicitiPerm
@@ -0,0 +1,27 @@
+
+as testid@aaf.att.com
+# TC_User1.43.1.POS Add another user to worker role
+expect 201
+user role add m99995@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+
+
+as m99990@@[user.name].TC_User1.test.com
+# TC_User1.43.2.POS User should only see himself here
+expect 200
+user list role com.test.TC_User1.@[user.name].worker
+user list perm com.test.TC_User1.@[user.name].supplies * move
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+
+
+as XX@NS
+# TC_User1.43.10.POS Grant explicit user perm to user
+expect 201
+perm create com.att.aaf.user :com.test.TC_User1.@[user.name] view com.test.TC_User1.@[user.name].worker
+
+as m99990@@[user.name].TC_User1.test.com
+# TC_User1.43.11.POS User should see all users of test domain now
+expect 200
+user list role com.test.TC_User1.@[user.name].worker
+user list perm com.test.TC_User1.@[user.name].supplies * move
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+
diff --git a/authz-test/TestSuite/TC_User1/99_cleanup b/authz-test/TestSuite/TC_User1/99_cleanup
new file mode 100644
index 0000000..f6e9724
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/99_cleanup
@@ -0,0 +1,37 @@
+expect 200,404
+as testid@aaf.att.com
+
+# TC_User1.99.0.POS Remove user roles 
+user role del @[user.name] com.test.TC_User1.@[user.name].manager
+user role del m99990@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+user role del m99995@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+
+# TC_User1.99.1.POS Namespace Admin can delete Namepace defined Roles & Perms
+force perm delete com.test.TC_User1.@[user.name].supplies * move 
+force perm delete com.test.TC_User1.@[user.name].supplies * stock 
+force perm delete com.test.TC_User1.@[user.name].schedule worker create 
+force perm delete com.test.TC_User1.@[user.name].worker * annoy 
+force role delete com.test.TC_User1.@[user.name].manager
+force role delete com.test.TC_User1.@[user.name].worker
+
+# TC_User1.99.10.POS Creds and delegate
+user delegate del @[user.name]
+user cred del m99990@@[user.name].TC_User1.test.com
+user cred del m99995@@[user.name].TC_User1.test.com
+
+as XX@NS
+# TC_User1.99.15.POS Remove ability to create creds
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_User1.@[user.name].cred_admin
+perm ungrant com.att.aaf.delg com.att change com.test.TC_User1.@[user.name].cred_admin
+perm delete com.att.aaf.user :com.test.TC_User1.@[user.name] view
+
+as testid@aaf.att.com:<pass>
+force role delete com.test.TC_User1.@[user.name].cred_admin
+
+# TC_User1.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_User1.@[user.name]
+sleep @[NFR]
+
+# TC_User1.99.99.POS Check Clean Namespace
+ns list name com.test.TC_User1.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_User1/Description b/authz-test/TestSuite/TC_User1/Description
new file mode 100644
index 0000000..9f74081
--- /dev/null
+++ b/authz-test/TestSuite/TC_User1/Description
@@ -0,0 +1,6 @@
+This Testcase Tests the viewability of different user commands
+
+APIs:	
+
+CLI:
+
diff --git a/authz-test/TestSuite/TC_Wild/00_ids b/authz-test/TestSuite/TC_Wild/00_ids
new file mode 100644
index 0000000..7fb0e05
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/00_ids
@@ -0,0 +1,8 @@
+expect 0
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set XX@NS=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TC_Wild/10_init b/authz-test/TestSuite/TC_Wild/10_init
new file mode 100644
index 0000000..c411f93
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/10_init
@@ -0,0 +1,18 @@
+as XX@NS
+# TC_Wild.10.0.POS Validate NS ok
+expect 200
+ns list name com.att.test.TC_Wild.@[user.name] 
+
+# TC_Wild.10.1.POS Create Namespace with valid IDs and Responsible Parties
+expect 201
+ns create com.att.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+
+# TC_Wild.10.10.POS Create a clean MechID
+expect 201
+user cred add m99999@@[user.name].TC_Wild.att.com aNewPass8
+set m99999@@[user.name].TC_Wild.att.com=aNewPass8
+
+as XX@NS
+# TC_Wild.10.11.POS Create role and assign MechID to
+expect 201
+role create com.att.TC_Wild.@[user.name].service m99999@@[user.name].TC_Wild.att.com
diff --git a/authz-test/TestSuite/TC_Wild/20_perm b/authz-test/TestSuite/TC_Wild/20_perm
new file mode 100644
index 0000000..2110cbe
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/20_perm
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.20.1.NEG Fail to create a perm in NS
+expect 403
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.20.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.TC_Wild.@[user.name].access :perm:myType:*:myAction write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.20.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.20.7.POS Now able to create a perm in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.20.8.POS Print Perms
+as XX@NS
+expect 200
+perm list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.20.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.TC_Wild.@[user.name].access :perm:myType:*:myAction write
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+
diff --git a/authz-test/TestSuite/TC_Wild/21_perm b/authz-test/TestSuite/TC_Wild/21_perm
new file mode 100644
index 0000000..772eea9
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/21_perm
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.21.1.NEG Fail to create a perm in NS
+expect 403
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.21.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.TC_Wild.@[user.name].access :perm:myType:*:* write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.21.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.21.7.POS Now able to create a perm in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.21.8.POS Print Perms
+as XX@NS
+expect 200
+perm list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.21.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.TC_Wild.@[user.name].access :perm:myType:*:* write
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+
diff --git a/authz-test/TestSuite/TC_Wild/30_role b/authz-test/TestSuite/TC_Wild/30_role
new file mode 100644
index 0000000..6d680c7
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/30_role
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.30.1.NEG Fail to create a role in NS
+expect 403
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.30.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.TC_Wild.@[user.name].access :role:tool.* write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.30.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.30.7.POS Now able to create a role in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.30.8.POS Print Perms
+as XX@NS
+expect 200
+role list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.30.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.TC_Wild.@[user.name].access :role:tool.* write
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+
diff --git a/authz-test/TestSuite/TC_Wild/31_role b/authz-test/TestSuite/TC_Wild/31_role
new file mode 100644
index 0000000..e29f308
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/31_role
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.31.1.NEG Fail to create a role in NS
+expect 403
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.31.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.TC_Wild.@[user.name].access :role:* write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.31.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.31.7.POS Now able to create a role in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.31.8.POS Print Perms
+as XX@NS
+expect 200
+role list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.31.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.TC_Wild.@[user.name].access :role:* write
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+
diff --git a/authz-test/TestSuite/TC_Wild/32_role b/authz-test/TestSuite/TC_Wild/32_role
new file mode 100644
index 0000000..ccbe866
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/32_role
@@ -0,0 +1,30 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.32.1.NEG Fail to create a role in NS
+expect 403
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+# TC_Wild.32.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.TC_Wild.@[user.name].access :role:* * com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.32.5.POS Print Perms
+as m99999@@[user.name].TC_Wild.att.com
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.32.7.POS Now able to create a role in NS
+expect 201
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+# TC_Wild.32.8.POS May Print Role
+expect 200
+role list role com.att.TC_Wild.@[user.name].tool.myRole
+
+as XX@NS
+# TC_Wild.32.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.TC_Wild.@[user.name].access :role:* *
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+
diff --git a/authz-test/TestSuite/TC_Wild/50_global_perm b/authz-test/TestSuite/TC_Wild/50_global_perm
new file mode 100644
index 0000000..df5f542
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/50_global_perm
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.50.1.NEG Fail to create a perm in NS
+expect 403
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.50.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.aaf.ns :com.att.*:perm:myType:*:* write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.50.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.50.7.POS Now able to create a perm in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+
+
+# TC_Wild.50.8.POS Print Perms
+as XX@NS
+expect 200
+perm list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.50.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.aaf.ns :com.att.*:perm:myType:*:* write 
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+
diff --git a/authz-test/TestSuite/TC_Wild/51_global_role b/authz-test/TestSuite/TC_Wild/51_global_role
new file mode 100644
index 0000000..1e86e91
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/51_global_role
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.51.1.NEG Fail to create a role in NS
+expect 403
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.51.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.aaf.ns :com.att.*:role:tool.* write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.51.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.51.7.POS Now able to create a role in NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+role create com.att.TC_Wild.@[user.name].tool.myRole
+
+
+# TC_Wild.51.8.POS Print Perms
+as XX@NS
+expect 200
+role list ns com.att.TC_Wild.@[user.name]
+
+# TC_Wild.51.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.aaf.ns :com.att.*:role:tool.* write
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+
diff --git a/authz-test/TestSuite/TC_Wild/52_global_ns b/authz-test/TestSuite/TC_Wild/52_global_ns
new file mode 100644
index 0000000..b1e45ad
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/52_global_ns
@@ -0,0 +1,33 @@
+as m99999@@[user.name].TC_Wild.att.com
+
+# TC_Wild.52.1.NEG Fail to create a NS
+expect 403
+ns create com.test.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+
+
+# TC_Wild.52.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+expect 201
+perm create com.att.aaf.ns :com.test:ns write com.att.TC_Wild.@[user.name].service
+
+# TC_Wild.52.5.POS Print Perms
+expect 200
+perm list user m99999@@[user.name].TC_Wild.att.com
+
+
+# TC_Wild.52.7.POS Now able to create an NS
+as m99999@@[user.name].TC_Wild.att.com
+expect 201
+ns create com.test.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+
+
+# TC_Wild.52.8.POS Print Perms
+as XX@NS
+expect 200
+ns list name com.test.TC_Wild.@[user.name]
+
+# TC_Wild.52.10.POS Delete Perms Created
+expect 200
+force perm delete com.att.aaf.ns :com.test:ns write
+force ns delete com.test.TC_Wild.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Wild/99_cleanup b/authz-test/TestSuite/TC_Wild/99_cleanup
new file mode 100644
index 0000000..d6abfd9
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/99_cleanup
@@ -0,0 +1,25 @@
+as XX@NS
+expect 200,404
+
+# TC_Wild.99.80.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:perm:*:* write 
+
+# TC_Wild.99.81.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:perm:*:* * 
+
+# TC_Wild.99.82.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:role:* write 
+
+# TC_Wild.99.83.POS Cleanup
+force perm delete com.att.aaf.ns :com.test:ns write
+
+# TC_Wild.99.90.POS Cleanup
+force ns delete com.test.TC_Wild.@[user.name]
+
+# TC_Wild.99.91.POS Cleanup
+force ns delete com.att.TC_Wild.@[user.name]
+
+# TC_Wild.99.99.POS List to prove clean Namespaces
+ns list name com.att.TC_Wild.@[user.name]
+ns list name com.test.TC_Wild.@[user.name]
+
diff --git a/authz-test/TestSuite/TC_Wild/Description b/authz-test/TestSuite/TC_Wild/Description
new file mode 100644
index 0000000..012a12b
--- /dev/null
+++ b/authz-test/TestSuite/TC_Wild/Description
@@ -0,0 +1,16 @@
+This Testcase Tests the essentials of the Namespace, and the NS Commands
+
+APIs:	
+
+
+
+CLI:
+   Target
+	role create :role
+	role delete 
+	ns delete :ns
+	ns list :ns
+   Ancillary
+	role create :role
+	role list name :role.*
+
diff --git a/authz-test/TestSuite/TEMPLATE_TC/00_ids b/authz-test/TestSuite/TEMPLATE_TC/00_ids
new file mode 100644
index 0000000..ad09d77
--- /dev/null
+++ b/authz-test/TestSuite/TEMPLATE_TC/00_ids
@@ -0,0 +1,10 @@
+expect 0
+set XX@NS=<pass>
+set testid@aaf.att.com=<pass>
+set testunused@aaf.att.com=<pass>
+set testid_1@test.com=<pass>
+set testid_2@test.com=<pass>
+set bogus=boguspass
+
+#delay 10
+set NFR=0
diff --git a/authz-test/TestSuite/TEMPLATE_TC/10_init b/authz-test/TestSuite/TEMPLATE_TC/10_init
new file mode 100644
index 0000000..ebdaaae
--- /dev/null
+++ b/authz-test/TestSuite/TEMPLATE_TC/10_init
@@ -0,0 +1,24 @@
+as XX@NS
+# TEMPLATE_TC.10.0.POS Print NS to prove ok
+expect 200
+ns list name com.test.TEMPLATE_TC.@[user.name] 
+
+# TEMPLATE_TC.10.1.POS Create Namespace with User ID
+expect 201
+ns create com.test.TEMPLATE_TC.@[user.name]_1 @[user.name] testid_1@test.com
+
+# TEMPLATE_TC.10.4.POS Print NS to prove ok
+expect 200
+ns list name com.test.TEMPLATE_TC.@[user.name]_2
+ 
+# TEMPLATE_TC.10.5.POS Create Namespace with Different ID
+expect 201
+ns create com.test.TEMPLATE_TC.@[user.name]_2 @[user.name] testid_2@test.com
+
+# TEMPLATE_TC.10.8.POS Print NS to prove ok
+expect 200
+ns list name com.att.TEMPLATE_TC.@[user.name]
+ 
+# TEMPLATE_TC.10.9.POS Create Namespace in Different Company
+expect 201
+ns create com.att.TEMPLATE_TC.@[user.name] @[user.name] testunused@aaf.att.com
diff --git a/authz-test/TestSuite/TEMPLATE_TC/99_cleanup b/authz-test/TestSuite/TEMPLATE_TC/99_cleanup
new file mode 100644
index 0000000..a208046
--- /dev/null
+++ b/authz-test/TestSuite/TEMPLATE_TC/99_cleanup
@@ -0,0 +1,22 @@
+expect 200,404
+as testid_1@test.com
+# TEMPLATE_TC.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TEMPLATE_TC.@[user.name]_1
+
+# TEMPLATE_TC.99.3.POS Print Namespaces
+ns list name com.test.TEMPLATE_TC.@[user.name]_1
+
+as testid_2@test.com
+# TEMPLATE_TC.99.4.POS Namespace Admin can delete Namespace
+force ns delete com.test.TEMPLATE_TC.@[user.name]_2
+
+# TEMPLATE_TC.99.5.POS Print Namespaces
+ns list name com.test.TEMPLATE_TC.@[user.name]_2
+
+
+as testunused@aaf.att.com
+# TEMPLATE_TC.99.6.POS Remove Namespace from other company
+force ns delete com.att.TEMPLATE_TC.@[user.name]
+
+# TEMPLATE_TC.99.7.POS Print Namespace from other company
+ns list name com.att.TEMPLATE_TC.@[user.name]
diff --git a/authz-test/TestSuite/TEMPLATE_TC/Description b/authz-test/TestSuite/TEMPLATE_TC/Description
new file mode 100644
index 0000000..2283774
--- /dev/null
+++ b/authz-test/TestSuite/TEMPLATE_TC/Description
@@ -0,0 +1,10 @@
+This is a TEMPLATE testcase, to make creating new Test Cases easier.
+
+APIs:	
+
+
+CLI:
+ns create
+ns delete
+as
+
diff --git a/authz-test/TestSuite/cmds b/authz-test/TestSuite/cmds
new file mode 100644
index 0000000..4d3c6ab
--- /dev/null
+++ b/authz-test/TestSuite/cmds
@@ -0,0 +1,21 @@
+# /bin/bash
+. ~/.bashrc
+function failed {
+     echo "FAILED TEST! " $*
+     exit 1
+}
+
+if [ "$1" == "" ] ; then 
+  DIRS=`find . -name "TC_*" -maxdepth 1`" "`find . -name "MTC_*" -maxdepth 1`
+else
+  DIRS="$1"
+fi
+
+  for DIR in $DIRS; do 
+    for FILE in $DIR/[0-9]*; do 
+       echo "*** "$FILE" ***"
+       cat $FILE
+       echo
+    done
+   done
+exit 0
diff --git a/authz-test/TestSuite/copy b/authz-test/TestSuite/copy
new file mode 100644
index 0000000..27d57cb
--- /dev/null
+++ b/authz-test/TestSuite/copy
@@ -0,0 +1,17 @@
+# /bin/bash
+if [ "$2" != "" ] ; then 
+  if [ -e $2 ]; then
+     echo "$2 exists, copy aborted"
+     exit 1
+  fi
+  mkdir -p $2
+  for FILE in $1/*; do 
+     FILE2=`echo $FILE | sed -e "s/$1/$2/"`
+     echo $FILE2
+     sed -e "s/$1/$2/g" $FILE > $FILE2
+  done
+else
+  echo 'Usage: copy <Source TestCase> <Target TestCase>'
+fi
+
+exit 0
diff --git a/authz-test/TestSuite/csv b/authz-test/TestSuite/csv
new file mode 100644
index 0000000..a6a0b30
--- /dev/null
+++ b/authz-test/TestSuite/csv
@@ -0,0 +1,13 @@
+# /bin/bash
+if [ "$1" == "" ]; then
+   DIRS=`ls -d TC*`
+else
+   DIRS=$1
+fi
+
+echo '"Test Case","Description"'
+for DIR in $DIRS; do 
+  grep -h "^# $DIR" $DIR/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /,"/' -e 's/$/"/'
+done
+cd ..
+exit 0
diff --git a/authz-test/TestSuite/expected/MTC_Appr1.expected b/authz-test/TestSuite/expected/MTC_Appr1.expected
new file mode 100644
index 0000000..269f731
--- /dev/null
+++ b/authz-test/TestSuite/expected/MTC_Appr1.expected
@@ -0,0 +1,144 @@
+set testid@aaf.att.com <pass>
+set XX@NS <pass>
+set testunused@aaf.att.com <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Appr1.10.0.POS List NS to prove ok
+ns list name com.test.appr
+** Expect 200 **
+
+List Namespaces by Name[com.test.appr]
+--------------------------------------------------------------------------------
+
+ns list name com.test.appr.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.appr.@[THE_USER]]
+--------------------------------------------------------------------------------
+
+# TC_Appr1.10.1.POS Create Personalized Namespace to add Approvals
+ns create com.test.appr.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Appr1.10.2.POS Create General Namespace to add Approvals
+ns create com.test.appr @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Appr1.10.10.POS Create Roles in Namespace
+role create com.test.appr.@[user.name].addToUserRole
+** Expect 201 **
+Created Role
+
+role create com.test.appr.@[user.name].grantToPerm
+** Expect 201 **
+Created Role
+
+role create com.test.appr.@[user.name].ungrantFromPerm
+** Expect 201 **
+Created Role
+
+role create com.test.appr.@[user.name].grantFirstPerm
+** Expect 201 **
+Created Role
+
+role create com.test.appr.@[user.name].grantSecondPerm
+** Expect 201 **
+Created Role
+
+# TC_Appr1.10.12.POS Create Permissions in Namespace
+perm create com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.appr.@[THE_USER].ungrantFromRole|myInstance|myAction] to Role [com.test.appr.@[THE_USER].ungrantFromPerm]
+
+perm create com.test.appr.@[user.name].grantToRole myInstance myAction
+** Expect 201 **
+Created Permission
+
+force perm create com.test.appr.@[user.name].deleteThisPerm myInstance myAction com.test.appr.@[user.name].grantedRole
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.appr.@[THE_USER].deleteThisPerm|myInstance|myAction] to Role [com.test.appr.@[THE_USER].grantedRole] (Created)
+
+perm create com.test.appr.@[user.name].grantTwoRoles myInstance myAction
+** Expect 201 **
+Created Permission
+
+perm create com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.appr.@[THE_USER].ungrantTwoRoles|myInstance|myAction] to Role [com.test.appr.@[THE_USER].grantFirstPerm]
+Granted Permission [com.test.appr.@[THE_USER].ungrantTwoRoles|myInstance|myAction] to Role [com.test.appr.@[THE_USER].grantSecondPerm]
+
+as testunused@aaf.att.com
+# TC_Appr1.15.01.NEG Create Future and Approvals with non-admin request
+user role add @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].addToUserRole
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.02.NEG Create Approval for NS create
+ns create com.test.appr.@[user.name].myProject @[user.name]
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.03.NEG Generate Approval for granting permission to role
+perm grant com.test.appr.@[user.name].grantToRole myInstance myAction com.test.appr.@[user.name].grantToPerm
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.04.NEG Generate Approval for ungranting permission from role
+perm ungrant com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.05.NEG Generate Approval for granting permission to role
+perm grant com.test.appr.@[user.name].grantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.06.NEG Generate Approval for ungranting permission from role
+perm ungrant com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+** Expect 403 **
+Failed [SVC2403]: Approvals required, but not requested by Client
+Failed [SVC2403]: Approvals required, but not requested by Client
+
+# TC_Appr1.15.51.POS Create Future and Approvals with non-admin request
+set request true
+set request=true user role add @[user.name]@@[user.name].appr.test.com com.test.appr.@[user.name].addToUserRole
+** Expect 202 **
+UserRole Creation Accepted, but requires Approvals before actualizing
+
+# TC_Appr1.15.52.POS Create Approval for NS create
+set request true
+set request=true ns create com.test.appr.@[user.name].myProject @[user.name]
+** Expect 202 **
+Namespace Creation Accepted, but requires Approvals before actualizing
+
+# TC_Appr1.15.53.POS Generate Approval for granting permission to role
+set request true
+set request=true perm grant com.test.appr.@[user.name].grantToRole myInstance myAction com.test.appr.@[user.name].grantToPerm
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Appr1.15.54.POS Generate Approval for ungranting permission from role
+request perm ungrant com.test.appr.@[user.name].ungrantFromRole myInstance myAction com.test.appr.@[user.name].ungrantFromPerm
+** Expect 202 **
+Permission Role Ungranted Accepted, but requires Approvals before actualizing
+
+# TC_Appr1.15.55.POS Generate Approval for granting permission to role
+request perm grant com.test.appr.@[user.name].grantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Appr1.15.56.POS Generate Approval for ungranting permission from role
+request perm ungrant com.test.appr.@[user.name].ungrantTwoRoles myInstance myAction com.test.appr.@[user.name].grantFirstPerm,com.test.appr.@[user.name].grantSecondPerm
+** Expect 202 **
+Permission Role Ungranted Accepted, but requires Approvals before actualizing
+Permission Role Ungranted Accepted, but requires Approvals before actualizing
+
diff --git a/authz-test/TestSuite/expected/MTC_Appr2.expected b/authz-test/TestSuite/expected/MTC_Appr2.expected
new file mode 100644
index 0000000..7191a04
--- /dev/null
+++ b/authz-test/TestSuite/expected/MTC_Appr2.expected
@@ -0,0 +1,24 @@
+# TC_Appr2.99.1.POS Delete User Role, if exists
+user role del testunused@aaf.att.com com.test.appr.@[user.name].myRole
+** Expect 200,404 **
+Failed [SVC1404]: Cannot delete non-existent User Role
+
+# TC_Appr2.99.79.POS Delete Role
+role delete com.test.appr.@[user.name].myRole
+** Expect 200,404 **
+Deleted Role
+
+# TC_Appr2.99.80.POS Delete Namespaces for TestSuite 
+ns delete com.test.appr
+** Expect 200,404 **
+Deleted Namespace
+
+ns delete com.test.appr.@[user.name] 
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Appr2.99.81.POS Delete Credential used to generate approvals
+as XX@NS:<pass> user cred del testbatch@aaf.att.com
+** Expect 200,404 **
+Deleted Credential [testbatch@aaf.att.com]
+
diff --git a/authz-test/TestSuite/expected/TC_Cred1.expected b/authz-test/TestSuite/expected/TC_Cred1.expected
new file mode 100644
index 0000000..8d310d9
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Cred1.expected
@@ -0,0 +1,269 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus boguspass
+set XX@NS <pass>
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Cred1.10.0.POS List NS to prove ok
+ns list name com.test.TC_Cred1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Cred1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Cred1.10.1.POS Create Personalized Namespace to add Credentials
+ns create com.test.TC_Cred1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Cred1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_Cred1.@[user.name].cred_admin testid@aaf.att.com
+** Expect 201 **
+Created Role
+Added User [testid@aaf.att.com] to Role [com.test.TC_Cred1.@[THE_USER].cred_admin]
+
+role create com.test.TC_Cred1.@[user.name].pw_reset 
+** Expect 201 **
+Created Role
+
+# TC_Cred1.10.11.POS Assign roles to perms
+as XX@NS
+perm create com.att.aaf.password com.test reset com.test.TC_Cred1.@[user.name].pw_reset
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.password|com.test|reset] to Role [com.test.TC_Cred1.@[THE_USER].pw_reset]
+
+perm create com.att.aaf.mechid com.test create com.test.TC_Cred1.@[user.name].cred_admin 
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.mechid|com.test|create] to Role [com.test.TC_Cred1.@[THE_USER].cred_admin]
+
+perm grant com.att.aaf.mechid com.att create com.test.TC_Cred1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_Cred1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_Cred1.10.30.POS Assign user for creating creds
+user cred add m99999@@[user.name].TC_Cred1.test.com password123
+** Expect 201 **
+Added Credential [m99999@@[THE_USER].TC_Cred1.test.com]
+
+set m99999@@[THE_USER].TC_Cred1.test.com password123
+# TC_Cred1.10.31.POS Credential used to similate non-admin Tier1 user with reset and create permissions
+user role add m99999@@[user.name].TC_Cred1.test.com com.test.TC_Cred1.@[user.name].pw_reset,com.test.TC_Cred1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_Cred1.@[THE_USER].pw_reset] to User [m99999@@[THE_USER].TC_Cred1.test.com]
+Added Role [com.test.TC_Cred1.@[THE_USER].cred_admin] to User [m99999@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.10.32.POS Remove create rights for testing
+user role del testid@aaf.att.com com.test.TC_Cred1.@[user.name].cred_admin 
+** Expect 200 **
+Removed Role [com.test.TC_Cred1.@[THE_USER].cred_admin] from User [testid@aaf.att.com]
+
+# TC_Cred1.15.1.NEG Non-Admin, no permission user cannot create mechID
+as testunused@aaf.att.com
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 403 **
+Failed [SVC1403]: Forbidden - testunused@aaf.att.com does not have permission to create MechIDs at AT&T
+
+# TC_Cred1.15.3.POS Non-Admin, with create permission user can create mechID
+as m99999@@[THE_USER].TC_Cred1.test.com
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.15.10.NEG Non-Admin, no reset permission cannot reset mechID
+as testunused@aaf.att.com
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 403 **
+Failed [SVC1403]: Forbidden - testunused@aaf.att.com is not allowed to change m99990@@[THE_USER].TC_Cred1.test.com in com.test.TC_Cred1.@[THE_USER]
+
+# TC_Cred1.15.11.POS Non-Admin, with reset permission can reset mechID
+as m99999@@[THE_USER].TC_Cred1.test.com
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 200 **
+Reset Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.15.12.POS Admin, without reset permission can reset Password
+as testid@aaf.att.com
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 200 **
+Reset Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.15.15.POS Admin, without reset permission can reset mechID
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 1
+** Expect 200 **
+Reset Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.15.20.POS Admin, delete
+user cred del m99990@@[user.name].TC_Cred1.test.com password123 1
+** Expect 200 **
+Deleted Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.30.1.NEG Multiple options available to delete
+as XX@NS
+user cred add m99990@@[user.name].TC_Cred1.test.com pass23Word
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+as testid@aaf.att.com
+user cred add m99990@@[user.name].TC_Cred1.test.com pass23worD
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.30.2.POS Succeeds when we choose last option
+user cred del m99990@@[user.name].TC_Cred1.test.com 2
+** Expect 200 **
+Deleted Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.30.10.POS Add another credential
+user cred add m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.30.11.NEG Multiple options available to reset
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123
+** Expect 300 **
+Failed [SVC1300]: Choice - Select which cred to update:
+       Id                                Type  Expires
+    1) m99990@@[THE_USER].TC_Cred1.test.com    2    [Placeholder]
+    2) m99990@@[THE_USER].TC_Cred1.test.com    2    [Placeholder]
+Run same command again with chosen entry as last parameter
+
+# TC_Cred1.30.12.NEG Fails when we choose a bad option
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 0 
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - User chose invalid credential selection
+
+# TC_Cred1.30.13.POS Succeeds when we choose last option
+user cred reset m99990@@[user.name].TC_Cred1.test.com password123 2
+** Expect 200 **
+Reset Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+#TC_Cred1.30.30.NEG Fails when we don't have specific property
+user cred extend m99990@@[user.name].TC_Cred1.test.com 
+** Expect 403 **
+Failed [SVC3403]: Forbidden - testid@aaf.att.com does not have permission to extend passwords at AT&T
+
+#### EXTENDS behavior ####
+#TC_Cred1.30.32.POS Setup Temp Role for Extend Permission
+as XX@NS
+role create com.test.TC_Cred1.@[user.name].extendTemp
+** Expect 201 **
+Created Role
+
+#TC_Cred1.30.33.POS Grant Extends Permission to Role
+perm grant com.att.aaf.password com.att extend com.test.TC_Cred1.@[user.name].extendTemp 
+** Expect 201 **
+Granted Permission [com.att.aaf.password|com.att|extend] to Role [com.test.TC_Cred1.@[THE_USER].extendTemp]
+
+#TC_Cred1.30.35.POS Add current User to Temp Role for Extend Permission
+role user add com.test.TC_Cred1.@[user.name].extendTemp XX@NS
+** Expect 201 **
+Added User [XX@NS] to Role [com.test.TC_Cred1.@[THE_USER].extendTemp]
+
+#TC_Cred1.30.36.POS Extend Password, expecting Single Response
+user cred extend m99990@@[user.name].TC_Cred1.test.com 1
+** Expect 200 **
+Extended Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+#TC_Cred1.30.39.POS Remove Role
+set force true
+role delete com.test.TC_Cred1.@[user.name].extendTemp
+** Expect 200 **
+Deleted Role
+
+#### MULTI CLEANUP #####
+role list user m99990@@[user.name].TC_Cred1.test.com 
+** Expect 200 **
+
+List Roles for User [m99990@@[THE_USER].TC_Cred1.test.com]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+
+# TC_Cred1.30.80.POS Delete all entries for this cred
+set force true
+user cred del m99990@@[user.name].TC_Cred1.test.com 
+** Expect 200 **
+Deleted Credential [m99990@@[THE_USER].TC_Cred1.test.com]
+
+# TC_Cred1.30.99.POS List ns shows no creds attached
+ns list name com.test.TC_Cred1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Cred1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Cred1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Cred1.@[THE_USER].admin                                          
+        com.test.TC_Cred1.@[THE_USER].cred_admin                                     
+        com.test.TC_Cred1.@[THE_USER].owner                                          
+        com.test.TC_Cred1.@[THE_USER].pw_reset                                       
+    Permissions
+        com.test.TC_Cred1.@[THE_USER].access *                        *              
+        com.test.TC_Cred1.@[THE_USER].access *                        read           
+    Credentials
+        m99999@@[THE_USER].TC_Cred1.test.com                                         
+
+as testid@aaf.att.com
+# TC_Cred1.99.1.POS Delete credentials
+force user cred del m99990@@[user.name].TC_Cred1.test.com 
+** Expect 200,404 **
+Failed [SVC5404]: Not Found - Credential does not exist
+
+#TC_Cred1.99.2.POS Ensure Remove Role 
+set force true
+role delete com.test.TC_Cred1.@[user.name].extendTemp
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Cred1.@[THE_USER].extendTemp] does not exist
+
+# TC_Cred1.99.10.POS Remove ability to create creds
+force user role del testid@aaf.att.com com.test.TC_Cred1.@[user.name].cred_admin
+** Expect 200,404 **
+Failed [SVC6404]: Not Found - User [ testid@aaf.att.com ] is not Assigned to the Role [ com.test.TC_Cred1.@[THE_USER].cred_admin ]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Cred1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_Cred1.@[THE_USER].cred_admin]
+
+force perm delete com.att.aaf.password com.test reset
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.att.aaf.mechid com.test create
+** Expect 200,404 **
+Deleted Permission
+
+as testid@aaf.att.com
+force role delete com.test.TC_Cred1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Cred1.@[user.name].pw_reset
+** Expect 200,404 **
+Deleted Role
+
+# TC_Cred1.99.99.POS Delete Namespace for TestSuite 
+set force true
+set force=true ns delete com.test.TC_Cred1.@[user.name] 
+** Expect 200,404 **
+Deleted Namespace
+
+as XX@NS
+force ns delete com.test.TC_Cred1.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test.TC_Cred1.@[THE_USER] does not exist
+
+force ns delete com.test.TC_Cred1
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test.TC_Cred1 does not exist
+
diff --git a/authz-test/TestSuite/expected/TC_DELG1.expected b/authz-test/TestSuite/expected/TC_DELG1.expected
new file mode 100644
index 0000000..962caf6
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_DELG1.expected
@@ -0,0 +1,223 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set m99999@@[THE_USER].delg.test.com password123
+set bogus@aaf.att.com boguspass
+#delay 10
+set NFR 0
+# TC_DELG1.10.1.POS Check For Existing Data
+as testid@aaf.att.com
+ns list name com.test.delg.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.delg.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+as XX@NS
+perm create com.att.aaf.delg com.att * com.att.admin
+** Expect 201,409 **
+Failed [SVC1409]: Conflict Already Exists - Permission [com.att.aaf.delg|com.att|*] already exists.
+
+user list delegates delegate @[user.name]@csp.att.com
+** Expect 404 **
+Failed [SVC7404]: Not Found - Delegate [@[THE_USER]@csp.att.com] is not delegating for anyone.
+
+as testid@aaf.att.com
+# TC_DELG1.10.2.POS Create Namespace to add IDs
+ns create com.test.delg.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+as XX@NS
+# TC_DELG1.10.10.POS Grant ability to change delegates
+force perm grant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+** Expect 404 **
+Failed [SVC3404]: Not Found - Role [com.test.delg.@[THE_USER].change_delg] does not exist
+
+# TC_DELG1.10.11.POS Grant ability to change delegates
+role create com.test.delg.@[user.name].change_delg
+** Expect 201 **
+Created Role
+
+# TC_DELG1.10.12.POS Grant ability to change delegates
+force perm grant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.delg.@[THE_USER].change_delg]
+
+# TC_DELG1.10.14.POS Create user role to change delegates
+user role add testid@aaf.att.com com.test.delg.@[user.name].change_delg
+** Expect 201 **
+Added Role [com.test.delg.@[THE_USER].change_delg] to User [testid@aaf.att.com]
+
+# TC_DELG1.10.15.POS Grant ability to create cred
+perm grant com.att.aaf.delg com.att create com.test.delg.@[user.name].change_delg
+** Expect 201 **
+Granted Permission [com.att.aaf.delg|com.att|create] to Role [com.test.delg.@[THE_USER].change_delg]
+
+as testid@aaf.att.com
+# TC_DELG1.10.30.POS Create cred that will change his own delg
+user cred add m99999@@[user.name].delg.test.com password123
+** Expect 201 **
+Added Credential [m99999@@[THE_USER].delg.test.com]
+
+as XX@NS
+Unknown Instruction "TC_DELG1.10.31.POS"
+perm ungrant com.att.aaf.mechid com.att create com.test.delg.@[user.name].change_delg
+** Expect 200 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.delg.@[THE_USER].change_delg]
+
+as testid@aaf.att.com
+# TC_DELG1.10.99.POS Check for Data as Correct
+ns list name com.test.delg.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.delg.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.delg.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.delg.@[THE_USER].admin                                              
+        com.test.delg.@[THE_USER].change_delg                                        
+        com.test.delg.@[THE_USER].owner                                              
+    Permissions
+        com.test.delg.@[THE_USER].access    *                        *              
+        com.test.delg.@[THE_USER].access    *                        read           
+    Credentials
+        m99999@@[THE_USER].delg.test.com                                             
+
+# TC_DELG1.20.10.NEG Cannot create delegate with unknown user ID
+user delegate add aa111q@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 404 **
+Failed [SVC5404]: Not Found - [aa111q@csp.att.com] is not a user in the company database.
+
+# TC_DELG1.20.11.NEG Cannot Create Delegate with unknown delegate
+user delegate add @[user.name]@csp.att.com aa111q@csp.att.com '2099-12-31 06:00'
+** Expect 404 **
+Failed [SVC5404]: Not Found - [aa111q@csp.att.com] is not a user in the company database.
+
+# TC_DELG1.20.20.NEG May not change user, no delegate permission
+as m99999@@[THE_USER].delg.test.com
+force user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].delg.test.com] may not create a delegate for [@[THE_USER]@csp.att.com]
+
+as testid@aaf.att.com
+# TC_DELG1.20.21.NEG Fail to Update Delegate that doesnt exist
+user delegate upd @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 404 **
+Failed [SVC1404]: Not Found - [@[THE_USER]@csp.att.com] does not have a Delegate Record to [write].
+
+# TC_DELG1.20.22.NEG May not create delegate for self. 
+user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - [@[THE_USER]@csp.att.com] cannot be a delegate for self
+
+# TC_DELG1.20.23.POS May create delegate for self for tests by forcing.
+force user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 201 **
+Delegate Added
+
+as XX@NS
+# TC_DELG1.20.30.POS Expect Delegates for User
+user list delegates user @[user.name]@csp.att.com
+** Expect 200 **
+
+List Delegates by user[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+as testid@aaf.att.com
+# TC_DELG1.20.35.NEG Fail Create when exists 
+user delegate add @[user.name]@csp.att.com @[user.name]@csp.att.com '2099-12-31 06:00'
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - [@[THE_USER]@csp.att.com] already delegates to [@[THE_USER]@csp.att.com]
+
+as XX@NS
+# TC_DELG1.20.40.POS Expect Delegates for User
+user list delegates user @[user.name]@csp.att.com
+** Expect 200 **
+
+List Delegates by user[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+as testid@aaf.att.com
+# TC_DELG1.20.46.POS Update Delegate with new Date
+user delegate upd @[user.name]@csp.att.com @[user.name]@csp.att.com '2999-01-01 06:00'
+** Expect 200 **
+Delegate Updated
+
+as XX@NS
+# TC_DELG1.20.82.POS Expect Delegates for User
+user list delegates user @[user.name]@csp.att.com
+** Expect 200 **
+
+List Delegates by user[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+# TC_DELG1.20.83.POS Expect Delegate to show up in list
+user list delegates delegate @[user.name]@csp.att.com
+** Expect 200 **
+
+List Delegates by delegate[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+as XX@NS
+# TC_DELG1.99.0.POS Check for Data as Correct
+ns list name com.test.delg.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.delg.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.delg.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.delg.@[THE_USER].admin                                              
+        com.test.delg.@[THE_USER].change_delg                                        
+        com.test.delg.@[THE_USER].owner                                              
+    Permissions
+        com.test.delg.@[THE_USER].access    *                        *              
+        com.test.delg.@[THE_USER].access    *                        read           
+    Credentials
+        m99999@@[THE_USER].delg.test.com                                             
+
+# TC_DELG1.99.10.POS Delete Delegates
+user delegate del @[user.name]@csp.att.com 
+** Expect 200,404 **
+Delegate Deleted
+
+# TC_DELG1.99.30.POS Delete Namespace com.att.test.id
+force ns delete com.test.delg.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_DELG1.99.98.POS Check for Delegate Data as Correct
+user list delegates user @[user.name]@csp.att.com 
+** Expect 200,404 **
+Failed [SVC7404]: Not Found - No Delegate found for [@[THE_USER]@csp.att.com]
+
+# TC_DELG1.99.99.POS Check for NS Data as Correct
+ns list name com.test.delg.@[user.name] 
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.delg.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Link.expected b/authz-test/TestSuite/expected/TC_Link.expected
new file mode 100644
index 0000000..3c58002
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Link.expected
@@ -0,0 +1,253 @@
+set testid <pass>
+set testid@aaf.att.com <pass>
+set XX@NS <pass>
+set testunused <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+# TC_05
+ns list name com.test.TC_Link_1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Link_1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Link_2.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Link_2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+perm list role com.test.TC_Link_1.@[user.name].myRole
+** Expect 200,404 **
+
+List Perms by Role [com.test.TC_Link_1.@[THE_USER].myRole]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+** Expect 200,404 **
+
+List Roles by Perm com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+
+# TC_10
+as XX@NS
+ns create com.test.TC_Link_1.@[user.name] @[user.name] XX@NS
+** Expect 201 **
+Created Namespace
+
+ns create com.test.TC_Link_2.@[user.name] @[user.name] XX@NS
+** Expect 201 **
+Created Namespace
+
+role create com.test.TC_Link_1.@[user.name].myRole
+** Expect 201 **
+Created Role
+
+perm create com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+** Expect 201 **
+Created Permission
+
+perm grant com.test.TC_Link_2.@[user.name].myPerm myInstance myAction com.test.TC_Link_1.@[user.name].myRole
+** Expect 201 **
+Granted Permission [com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction] to Role [com.test.TC_Link_1.@[THE_USER].myRole]
+
+# 15_print
+ns list name com.test.TC_Link_1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_1.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_1.@[THE_USER].admin                                         
+        com.test.TC_Link_1.@[THE_USER].myRole                                        
+        com.test.TC_Link_1.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_1.@[THE_USER].access *                        *              
+        com.test.TC_Link_1.@[THE_USER].access *                        read           
+
+ns list name com.test.TC_Link_2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_2.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_2.@[THE_USER].admin                                         
+        com.test.TC_Link_2.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_2.@[THE_USER].access *                        *              
+        com.test.TC_Link_2.@[THE_USER].access *                        read           
+        com.test.TC_Link_2.@[THE_USER].myPerm myInstance               myAction       
+
+perm list role com.test.TC_Link_1.@[user.name].myRole
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Link_1.@[THE_USER].myRole]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Link_2.@[THE_USER].myPerm myInstance                     myAction  
+
+
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Link_1.@[THE_USER].myRole                  
+   com.test.TC_Link_2.@[THE_USER].myPerm myInstance                     myAction       
+
+role delete com.test.TC_Link_1.@[user.name].myRole
+** Expect 200 **
+Deleted Role
+
+# 15_print
+ns list name com.test.TC_Link_1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_1.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_1.@[THE_USER].admin                                         
+        com.test.TC_Link_1.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_1.@[THE_USER].access *                        *              
+        com.test.TC_Link_1.@[THE_USER].access *                        read           
+
+ns list name com.test.TC_Link_2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_2.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_2.@[THE_USER].admin                                         
+        com.test.TC_Link_2.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_2.@[THE_USER].access *                        *              
+        com.test.TC_Link_2.@[THE_USER].access *                        read           
+        com.test.TC_Link_2.@[THE_USER].myPerm myInstance               myAction       
+
+perm list role com.test.TC_Link_1.@[user.name].myRole
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Link_1.@[THE_USER].myRole]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+
+role create com.test.TC_Link_1.@[user.name].myRole
+** Expect 201 **
+Created Role
+
+perm grant com.test.TC_Link_2.@[user.name].myPerm myInstance myAction com.test.TC_Link_1.@[user.name].myRole
+** Expect 201 **
+Granted Permission [com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction] to Role [com.test.TC_Link_1.@[THE_USER].myRole]
+
+# 15_print
+ns list name com.test.TC_Link_1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_1.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_1.@[THE_USER].admin                                         
+        com.test.TC_Link_1.@[THE_USER].myRole                                        
+        com.test.TC_Link_1.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_1.@[THE_USER].access *                        *              
+        com.test.TC_Link_1.@[THE_USER].access *                        read           
+
+ns list name com.test.TC_Link_2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Link_2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Link_2.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Link_2.@[THE_USER].admin                                         
+        com.test.TC_Link_2.@[THE_USER].owner                                         
+    Permissions
+        com.test.TC_Link_2.@[THE_USER].access *                        *              
+        com.test.TC_Link_2.@[THE_USER].access *                        read           
+        com.test.TC_Link_2.@[THE_USER].myPerm myInstance               myAction       
+
+perm list role com.test.TC_Link_1.@[user.name].myRole
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Link_1.@[THE_USER].myRole]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Link_2.@[THE_USER].myPerm myInstance                     myAction  
+
+
+role list perm com.test.TC_Link_2.@[user.name].myPerm myInstance myAction
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Link_2.@[THE_USER].myPerm|myInstance|myAction
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Link_1.@[THE_USER].myRole                  
+   com.test.TC_Link_2.@[THE_USER].myPerm myInstance                     myAction       
+
+as XX@NS
+force ns delete com.test.TC_Link_2.@[user.name] 
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test.TC_Link_1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
diff --git a/authz-test/TestSuite/expected/TC_NS1.expected b/authz-test/TestSuite/expected/TC_NS1.expected
new file mode 100644
index 0000000..6c5a89e
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_NS1.expected
@@ -0,0 +1,327 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus@aaf.att.com boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_NS1.01.0.POS Expect Clean Namespace to start
+ns list name com.test.TC_NS1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NS1.01.1.NEG Create Namespace with mechID as Responsible Party
+ns create com.test.TC_NS1.@[user.name] testunused@aaf.att.com testid@aaf.att.com,XX@NS
+** Expect 403 **
+Failed [SVC3403]: Forbidden - testunused@aaf.att.com does not have permission to assume test status at AT&T
+
+# TC_NS1.01.2.NEG Create Namespace with Bad ID for Admin
+ns create com.test.TC_NS1.@[user.name] @[user.name] bogus@aaf.att.com,XX@NS
+** Expect 403 **
+Failed [SVC2403]: Forbidden - bogus@aaf.att.com is not a valid AAF Credential
+
+as testid@aaf.att.com
+# TC_NS1.10.0.POS Check for Existing Data
+ns list name com.test.TC_NS1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NS1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_NS1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_NS1.10.40.POS Expect Namespace to be created
+ns list name com.test.TC_NS1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS1.@[THE_USER].admin                                            
+        com.test.TC_NS1.@[THE_USER].owner                                            
+    Permissions
+        com.test.TC_NS1.@[THE_USER].access  *                        *              
+        com.test.TC_NS1.@[THE_USER].access  *                        read           
+
+# TC_NS1.10.41.POS Expect Namespace to be created
+perm list role com.test.TC_NS1.@[user.name].admin
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS1.@[THE_USER].admin]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER].access  *                              *         
+
+
+# TC_NS1.10.42.POS Expect Namespace to be created
+perm list role com.test.TC_NS1.@[user.name].owner
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS1.@[THE_USER].owner]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER].access  *                              read      
+
+
+# TC_NS1.10.43.POS Expect Namespace to be created
+role list perm com.test.TC_NS1.@[user.name].access * *
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS1.@[THE_USER].access|*|*
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER].admin                      
+   com.test.TC_NS1.@[THE_USER].access  *                              *              
+
+# TC_NS1.10.44.POS Expect Namespace to be created
+role list perm com.test.TC_NS1.@[user.name].access * read
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS1.@[THE_USER].access|*|read
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER].owner                      
+   com.test.TC_NS1.@[THE_USER].access  *                              read           
+
+# TC_NS1.11.1.NEG Create Namespace when exists
+ns create com.test.TC_NS1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Target Namespace already exists
+
+# TC_NS1.20.1.NEG Too Few Args for Create 1
+ns create 
+** Expect -1 **
+Too few args: create <name> <responsible (id[,id]*)> [admin (id[,id]*)] 
+
+# TC_NS1.20.2.NEG Too Few Args for Create 2
+ns create bogus
+** Expect -1 **
+Too few args: create <name> <responsible (id[,id]*)> [admin (id[,id]*)] 
+
+# TC_NS1.30.10.NEG Non-admins can't change description
+as testunused@aaf.att.com
+ns describe com.test.TC_NS1.@[user.name] Description for my Namespace
+** Expect 403 **
+Failed [SVC1403]: Forbidden - You do not have approval to change com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.30.11.NEG Namespace must exist to change description
+as testid@aaf.att.com
+ns describe com.test.TC_NS1.@[user.name].project1 Description for my project
+** Expect 404 **
+Failed [SVC1404]: Not Found - Namespace [com.test.TC_NS1.@[THE_USER].project1] does not exist
+
+# TC_NS1.30.12.POS Admin can change description
+ns describe com.test.TC_NS1.@[user.name] Description for my Namespace
+** Expect 200 **
+Description added to Namespace
+
+# TC_NS1.50.1.NEG Adding a Bogus ID
+ns admin add com.test.TC_NS1.@[user.name] bogus
+** Expect 403 **
+Failed [SVC1403]: Forbidden - AT&T reports that bogus@csp.att.com is a faulty ID
+
+# TC_NS1.50.2.NEG Adding a Bogus ID, full Domain
+ns admin add com.test.TC_NS1.@[user.name] bogus@csp.att.com
+** Expect 403 **
+Failed [SVC1403]: Forbidden - AT&T reports that bogus@csp.att.com is a faulty ID
+
+# TC_NS1.50.3.NEG Adding an OK ID, bad domain
+ns admin add com.test.TC_NS1.@[user.name] xz9914@bogus.test.com
+** Expect 403 **
+Failed [SVC2403]: Forbidden - xz9914@bogus.test.com is not a valid AAF Credential
+
+# TC_NS1.50.4.NEG Deleting an OK ID, but not an admin
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [XX@NS] [com.test.TC_NS1.@[THE_USER].admin]
+
+sleep 0
+# TC_NS1.50.10.POS Adding an OK ID
+ns admin add com.test.TC_NS1.@[user.name] XX@NS
+** Expect 201 **
+Admin XX@NS added to com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.50.11.POS Deleting One of Two
+ns admin del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+** Expect 200 **
+Admin testid@aaf.att.com deleted from com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.50.12.NEG testid@aaf.att.com no longer Admin
+ns admin del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [testid@aaf.att.com] [com.test.TC_NS1.@[THE_USER].admin]
+
+# TC_NS1.50.13.POS Add ID back in
+ns admin add com.test.TC_NS1.@[user.name] testid@aaf.att.com
+** Expect 201 **
+Admin testid@aaf.att.com added to com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.50.14.POS Deleting original
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+** Expect 200 **
+Admin XX@NS deleted from com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.50.15.NEG Can't remove twice
+ns admin del com.test.TC_NS1.@[user.name] XX@NS
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [XX@NS] [com.test.TC_NS1.@[THE_USER].admin]
+
+# TC_NS1.50.20.NEG User Role Add should obey same "addAdmin" restrictions
+role user add com.test.TC_NS1.@[user.name].admin m88888@i.have.no.domain
+** Expect 403 **
+Failed [SVC2403]: Forbidden - m88888@i.have.no.domain is not a valid AAF Credential
+
+# TC_NS1.50.21.NEG Role User Add should obey same "addAdmin" restrictions
+user role add m88888@i.have.no.domain com.test.TC_NS1.@[user.name].admin 
+** Expect 403 **
+Failed [SVC2403]: Forbidden - m88888@i.have.no.domain is not a valid AAF Credential
+
+# TC_NS1.60.1.NEG Adding a Bogus ID
+ns responsible add com.test.TC_NS1.@[user.name] bogus
+** Expect 403 **
+Failed [SVC3403]: Forbidden - AT&T reports that this is not a valid credential
+
+# TC_NS1.60.2.NEG Adding a Bogus ID, full Domain
+ns responsible add com.test.TC_NS1.@[user.name] bogus@csp.att.com
+** Expect 403 **
+Failed [SVC3403]: Forbidden - AT&T reports that this is not a valid credential
+
+# TC_NS1.60.3.NEG Adding an OK ID, bad domain
+ns responsible add com.test.TC_NS1.@[user.name] xz9914@bogus.test.com
+** Expect 403 **
+Failed [SVC3403]: Forbidden - AT&T reports that this is not a valid credential
+
+# TC_NS1.60.4.NEG Deleting an OK ID, short, but not existent
+ns responsible del com.test.TC_NS1.@[user.name] testid
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [testid@csp.att.com] [com.test.TC_NS1.@[THE_USER].owner]
+
+# TC_NS1.60.5.NEG Deleting an OK ID, long, but not existent
+ns responsible del com.test.TC_NS1.@[user.name] testid@aaf.att.com
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [testid@aaf.att.com] [com.test.TC_NS1.@[THE_USER].owner]
+
+sleep 0
+# TC_NS1.60.10.POS Adding an OK ID
+# Note: mw9749 used because we must have employee as responsible
+ns responsible add com.test.TC_NS1.@[user.name] mw9749
+** Expect 201 **
+mw9749@csp.att.com is now responsible for com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.60.11.POS Deleting One of Two
+ns responsible del com.test.TC_NS1.@[user.name] mw9749
+** Expect 200 **
+mw9749@csp.att.com is no longer responsible for com.test.TC_NS1.@[THE_USER]
+
+# TC_NS1.60.12.NEG mw9749 no longer Admin
+ns responsible del com.test.TC_NS1.@[user.name] mw9749
+** Expect 404 **
+Failed [SVC6404]: Not Found - UserRole [mw9749@csp.att.com] [com.test.TC_NS1.@[THE_USER].owner]
+
+# TC_NS1.60.20.NEG User Role Add should obey same "addResponsible" restrictions
+role user add com.test.TC_NS1.@[user.name].owner m88888@i.have.no.domain
+** Expect 403 **
+Failed [SVC3403]: Forbidden - AT&T reports that this is not a valid credential
+
+# TC_NS1.60.21.NEG Role User Add should obey same "addResponsible" restrictions
+user role add m88888@i.have.no.domain com.test.TC_NS1.@[user.name].owner
+** Expect 403 **
+Failed [SVC3403]: Forbidden - AT&T reports that this is not a valid credential
+
+sleep 0
+# TC_NS1.80.1.POS List Data on Empty NS
+as testid@aaf.att.com
+ns list name com.test.TC_NS1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS1.@[THE_USER].admin                                            
+        com.test.TC_NS1.@[THE_USER].owner                                            
+    Permissions
+        com.test.TC_NS1.@[THE_USER].access  *                        *              
+        com.test.TC_NS1.@[THE_USER].access  *                        read           
+
+# TC_NS1.80.2.POS Add Roles to NS for Listing
+role create com.test.TC_NS1.@[user.name].r.A
+** Expect 201 **
+Created Role
+
+role create com.test.TC_NS1.@[user.name].r.B
+** Expect 201 **
+Created Role
+
+# TC_NS1.80.3.POS List Data on non-Empty NS
+ns list name com.test.TC_NS1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS1.@[THE_USER].admin                                            
+        com.test.TC_NS1.@[THE_USER].owner                                            
+        com.test.TC_NS1.@[THE_USER].r.A                                              
+        com.test.TC_NS1.@[THE_USER].r.B                                              
+    Permissions
+        com.test.TC_NS1.@[THE_USER].access  *                        *              
+        com.test.TC_NS1.@[THE_USER].access  *                        read           
+
+# TC_NS1.90.1.NEG Non Namespace Admin Delete Namespace
+as testunused@aaf.att.com
+ns delete com.test.TC_NS1.@[user.name]
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not write in NS [com.test.TC_NS1.@[THE_USER]]
+
+sleep 0
+as testid@aaf.att.com
+# TC_NS1.99.1.POS Namespace Admin can delete Namepace defined Roles
+role delete com.test.TC_NS1.@[user.name].r.A
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test.TC_NS1.@[user.name].r.B
+** Expect 200,404 **
+Deleted Role
+
+# TC_NS1.99.2.POS Namespace Admin can delete Namespace
+ns delete com.test.TC_NS1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+sleep 0
+# TC_NS1.99.99.POS Check Clean Namespace
+ns list name com.test.TC_NS1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_NS1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_NS2.expected b/authz-test/TestSuite/expected/TC_NS2.expected
new file mode 100644
index 0000000..f8de456
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_NS2.expected
@@ -0,0 +1,389 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus@aaf.att.com boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_NS2.10.0.POS Check for Existing Data
+ns list name com.test.TC_NS2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NS2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_NS2.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+ns create com.test.TC_NS2.@[user.name].project @[user.name] testunused@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_NS2.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_NS2.@[user.name].cred_admin testid@aaf.att.com
+** Expect 201 **
+Created Role
+Added User [testid@aaf.att.com] to Role [com.test.TC_NS2.@[THE_USER].cred_admin]
+
+as XX@NS
+# TC_NS2.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_NS2.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_NS2.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+ns list name com.test.TC_NS2.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS2.@[THE_USER].admin                                            
+        com.test.TC_NS2.@[THE_USER].cred_admin                                       
+        com.test.TC_NS2.@[THE_USER].owner                                            
+    Permissions
+        com.test.TC_NS2.@[THE_USER].access  *                        *              
+        com.test.TC_NS2.@[THE_USER].access  *                        read           
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+perm list role com.test.TC_NS2.@[user.name].admin
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS2.@[THE_USER].admin]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].access  *                              *         
+
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+perm list role com.test.TC_NS2.@[user.name].owner
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS2.@[THE_USER].owner]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].access  *                              read      
+
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+role list perm com.test.TC_NS2.@[user.name].access * *
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS2.@[THE_USER].access|*|*
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].admin                      
+   com.test.TC_NS2.@[THE_USER].access  *                              *              
+
+as testid@aaf.att.com
+# TC_NS2.10.70.POS Expect Namespace to be created
+role list perm com.test.TC_NS2.@[user.name].access * read
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS2.@[THE_USER].access|*|read
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].owner                      
+   com.test.TC_NS2.@[THE_USER].access  *                              read           
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+ns list name com.test.TC_NS2.@[user.name].project
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER].project]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project
+    Administrators
+        testunused@aaf.att.com                                                  
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS2.@[THE_USER].project.admin                                    
+        com.test.TC_NS2.@[THE_USER].project.owner                                    
+    Permissions
+        com.test.TC_NS2.@[THE_USER].project.access *                        *              
+        com.test.TC_NS2.@[THE_USER].project.access *                        read           
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+perm list role com.test.TC_NS2.@[user.name].project.admin
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS2.@[THE_USER].project.admin]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project.access *                              *         
+
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+perm list role com.test.TC_NS2.@[user.name].project.owner
+** Expect 200 **
+
+List Perms by Role [com.test.TC_NS2.@[THE_USER].project.owner]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project.access *                              read      
+
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+role list perm com.test.TC_NS2.@[user.name].project.access * *
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS2.@[THE_USER].project.access|*|*
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project.admin              
+   com.test.TC_NS2.@[THE_USER].project.access *                              *              
+
+as testid@aaf.att.com
+# TC_NS2.10.80.POS Expect Namespace to be created
+role list perm com.test.TC_NS2.@[user.name].project.access * read
+** Expect 200 **
+
+List Roles by Perm com.test.TC_NS2.@[THE_USER].project.access|*|read
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project.owner              
+   com.test.TC_NS2.@[THE_USER].project.access *                              read           
+
+as testid@aaf.att.com
+# TC_NS2.20.1.POS Create roles
+role create com.test.TC_NS2.@[user.name].watcher
+** Expect 201 **
+Created Role
+
+role create com.test.TC_NS2.@[user.name].myRole
+** Expect 201 **
+Created Role
+
+# TC_NS2.20.2.POS Create permissions
+perm create com.test.TC_NS2.@[user.name].myType myInstance myAction
+** Expect 201 **
+Created Permission
+
+perm create com.test.TC_NS2.@[user.name].myType * *
+** Expect 201 **
+Created Permission
+
+# TC_NS2.20.3.POS Create mechid
+user cred add m99990@@[user.name].TC_NS2.test.com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_NS2.test.com]
+
+as XX@NS
+# TC_NS2.20.10.POS Grant view perms to watcher role
+perm create com.att.aaf.ns :com.test.TC_NS2.@[user.name]:ns read com.test.TC_NS2.@[user.name].watcher
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.ns|:com.test.TC_NS2.@[THE_USER]:ns|read] to Role [com.test.TC_NS2.@[THE_USER].watcher]
+
+as testunused@aaf.att.com
+# TC_NS2.40.1.NEG Non-admin, not granted user should not view
+ns list name com.test.TC_NS2.@[user.name]
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read in NS [com.test.TC_NS2.@[THE_USER]]
+
+as testid@aaf.att.com
+# Tens test user granted to permission
+# TC_NS2.40.10.POS Add user to watcher role
+user role add testunused@aaf.att.com com.test.TC_NS2.@[user.name].watcher
+** Expect 201 **
+Added Role [com.test.TC_NS2.@[THE_USER].watcher] to User [testunused@aaf.att.com]
+
+as testunused@aaf.att.com
+# TC_NS2.40.11.POS Non-admin, granted user should view
+ns list name com.test.TC_NS2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS2.@[THE_USER].admin                                            
+        com.test.TC_NS2.@[THE_USER].cred_admin                                       
+        com.test.TC_NS2.@[THE_USER].myRole                                           
+        com.test.TC_NS2.@[THE_USER].owner                                            
+        com.test.TC_NS2.@[THE_USER].watcher                                          
+    Permissions
+        com.test.TC_NS2.@[THE_USER].access  *                        *              
+        com.test.TC_NS2.@[THE_USER].access  *                        read           
+        com.test.TC_NS2.@[THE_USER].myType  *                        *              
+        com.test.TC_NS2.@[THE_USER].myType  myInstance               myAction       
+    Credentials
+        m99990@@[THE_USER].TC_NS2.test.com                                           
+
+as testid@aaf.att.com
+# TC_NS2.40.19.POS Remove user from watcher role
+user role del testunused@aaf.att.com com.test.TC_NS2.@[user.name].watcher
+** Expect 200 **
+Removed Role [com.test.TC_NS2.@[THE_USER].watcher] from User [testunused@aaf.att.com]
+
+# Thirties test admin user 
+# TC_NS2.40.20.POS Admin should be able to view
+ns list name com.test.TC_NS2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS2.@[THE_USER].admin                                            
+        com.test.TC_NS2.@[THE_USER].cred_admin                                       
+        com.test.TC_NS2.@[THE_USER].myRole                                           
+        com.test.TC_NS2.@[THE_USER].owner                                            
+        com.test.TC_NS2.@[THE_USER].watcher                                          
+    Permissions
+        com.test.TC_NS2.@[THE_USER].access  *                        *              
+        com.test.TC_NS2.@[THE_USER].access  *                        read           
+        com.test.TC_NS2.@[THE_USER].myType  *                        *              
+        com.test.TC_NS2.@[THE_USER].myType  myInstance               myAction       
+    Credentials
+        m99990@@[THE_USER].TC_NS2.test.com                                           
+
+# TC_NS2.40.21.POS Admin of parent NS should be able to view
+ns list name com.test.TC_NS2.@[user.name].project
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER].project]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project
+    Administrators
+        testunused@aaf.att.com                                                  
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NS2.@[THE_USER].project.admin                                    
+        com.test.TC_NS2.@[THE_USER].project.owner                                    
+    Permissions
+        com.test.TC_NS2.@[THE_USER].project.access *                        *              
+        com.test.TC_NS2.@[THE_USER].project.access *                        read           
+
+# TC_NS2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+ns list admin testunused@aaf.att.com
+** Expect 200 **
+
+List Namespaces with admin privileges for [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project
+
+# TC_NS2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+ns list admin testunused@aaf.att.com
+** Expect 200 **
+
+List Namespaces with admin privileges for [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project
+
+# TC_NS2.41.20.POS List by User when not same as Caller, but parent owner of Namespace
+as XX@NS
+ns list admin testunused@aaf.att.com
+** Expect 200 **
+
+List Namespaces with admin privileges for [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+com.test.TC_NS2.@[THE_USER].project
+
+# TC_NS2.41.80.NEG List by User when not Caller nor associated to Namespace 
+as testunused@aaf.att.com
+ns list admin XX@NS
+** Expect 200 **
+
+List Namespaces with admin privileges for [XX@NS]
+--------------------------------------------------------------------------------
+com
+com.att
+com.att.aaf
+com.test
+
+as testid@aaf.att.com
+# TC_NS2.99.1.POS Namespace Admin can delete Namepace defined Roles & Perms
+role delete com.test.TC_NS2.@[user.name].myRole
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test.TC_NS2.@[user.name].watcher
+** Expect 200,404 **
+Deleted Role
+
+perm delete com.test.TC_NS2.@[user.name].myType myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+perm delete com.test.TC_NS2.@[user.name].myType * *
+** Expect 200,404 **
+Deleted Permission
+
+user cred del m99990@@[user.name].TC_NS2.test.com
+** Expect 200,404 **
+Deleted Credential [m99990@@[THE_USER].TC_NS2.test.com]
+
+as XX@NS
+force perm delete com.att.aaf.ns :com.test.TC_NS2.@[user.name]:ns read
+** Expect 200,404 **
+Deleted Permission
+
+# TC_NS2.99.15.POS Remove ability to create creds
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_NS2.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_NS2.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+force role delete com.test.TC_NS2.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_NS2.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_NS2.@[user.name].project
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test.TC_NS2.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+sleep 0
+# TC_NS2.99.99.POS Check Clean Namespace
+ns list name com.test.TC_NS2.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_NS2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_NS3.expected b/authz-test/TestSuite/expected/TC_NS3.expected
new file mode 100644
index 0000000..8ac3afc
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_NS3.expected
@@ -0,0 +1,192 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set testid_1@test.com <pass>
+set testid_2@test.com <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as XX@NS
+ns list name com.test.TC_NS3.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS3.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NS3.10.1.POS Create Namespace with User ID
+ns create com.test.TC_NS3.@[user.name]_1 @[user.name] testid_1@test.com
+** Expect 201 **
+Created Namespace
+
+as testid_1@test.com
+# TC_NS3.20.0.NEG Too short
+ns attrib
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.20.1.NEG Wrong command
+ns attrib xyz
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.20.2.NEG Too Short after Command
+ns attrib add
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.20.3.NEG Too Short after Namespace
+ns attrib add com.test.TC_NS3.@[user.name]
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.20.4.NEG Too Short after Key
+ns attrib add com.test.TC_NS3.@[user.name] TC_NS3_swm
+** Expect -1 **
+Not added: Need more Data
+
+# TC_NS3.20.5.NEG No Permission
+ns attrib add com.test.TC_NS3.@[user.name]_1 TC_NS3_swm v1
+** Expect 403 **
+Failed [SVC1403]: Forbidden - testid_1@test.com may not create NS Attrib [com.test.TC_NS3.@[THE_USER]_1:TC_NS3_swm]
+
+# TC_NS3.20.6.POS Create Permission to write Attrib
+as XX@NS
+perm create com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.attrib|:com.att.*:TC_NS3_swm|write] to Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+# TC_NS3.20.6.POS Create Permission
+perm create com.att.aaf.attrib :com.att.*:* read com.test.TC_NS3.@[user.name]_1.admin
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.attrib|:com.att.*:*|read] to Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+# TC_NS3.20.10.POS Attribute added
+as testid_1@test.com
+ns attrib add com.test.TC_NS3.@[user.name]_1 TC_NS3_swm v1
+** Expect 201 **
+Add Attrib TC_NS3_swm=v1 to com.test.TC_NS3.@[THE_USER]_1
+
+# TC_NS3.20.30.POS List NS by Attrib
+ns list keys TC_NS3_swm
+** Expect 200 **
+
+List Namespace Names by Attribute
+--------------------------------------------------------------------------------
+  com.test.TC_NS3.@[THE_USER]_1                                                
+
+# TC_NS3.20.40.POS List NS (shows Attrib)
+ns list name com.test.TC_NS3.@[user.name]_1
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS3.@[THE_USER]_1]
+--------------------------------------------------------------------------------
+com.test.TC_NS3.@[THE_USER]_1
+    Administrators
+        testid_1@test.com                                                       
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Namespace Attributes
+        TC_NS3_swm=v1                                                           
+    Roles
+        com.test.TC_NS3.@[THE_USER]_1.admin                                          
+        com.test.TC_NS3.@[THE_USER]_1.owner                                          
+    Permissions
+        com.test.TC_NS3.@[THE_USER]_1.access *                        *              
+        com.test.TC_NS3.@[THE_USER]_1.access *                        read           
+
+# TC_NS3.20.42.POS Change Attrib
+ns attrib upd com.test.TC_NS3.@[user.name]_1 TC_NS3_swm Version1
+** Expect 200 **
+Update Attrib TC_NS3_swm=Version1 for com.test.TC_NS3.@[THE_USER]_1
+
+# TC_NS3.20.49.POS List NS (shows new Attrib)
+ns list name com.test.TC_NS3.@[user.name]_1
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NS3.@[THE_USER]_1]
+--------------------------------------------------------------------------------
+com.test.TC_NS3.@[THE_USER]_1
+    Administrators
+        testid_1@test.com                                                       
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Namespace Attributes
+        TC_NS3_swm=Version1                                                     
+    Roles
+        com.test.TC_NS3.@[THE_USER]_1.admin                                          
+        com.test.TC_NS3.@[THE_USER]_1.owner                                          
+    Permissions
+        com.test.TC_NS3.@[THE_USER]_1.access *                        *              
+        com.test.TC_NS3.@[THE_USER]_1.access *                        read           
+
+# TC_NS3.20.80.POS Remove write Permission
+perm ungrant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+** Expect 200 **
+UnGranted Permission [com.att.aaf.attrib|:com.att.*:TC_NS3_swm|write] from Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+# TC_NS3.20.83.POS Remove read Permission
+perm ungrant com.att.aaf.attrib :com.att.*:* read com.test.TC_NS3.@[user.name]_1.admin
+** Expect 200 **
+UnGranted Permission [com.att.aaf.attrib|:com.att.*:*|read] from Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+as testid_1@test.com
+# TC_NS3.50.2.NEG Too Short after Command
+ns attrib del
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.50.3.NEG Too Short after Namespace
+ns attrib del com.test.TC_NS3.@[user.name]
+** Expect -1 **
+Too few args: attrib <add|upd|del> <ns> <key> [value] 
+
+# TC_NS3.50.5.NEG No Permission
+ns attrib del com.test.TC_NS3.@[user.name]_1 TC_NS3_swm 
+** Expect 403 **
+Failed [SVC1403]: Forbidden - testid_1@test.com may not delete NS Attrib [com.test.TC_NS3.@[THE_USER]_1:TC_NS3_swm]
+
+# TC_NS3.50.6.POS Create Permission
+as XX@NS
+perm grant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+** Expect 201 **
+Granted Permission [com.att.aaf.attrib|:com.att.*:TC_NS3_swm|write] to Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+# TC_NS3.50.7.POS Attribute added
+as testid_1@test.com
+ns attrib del com.test.TC_NS3.@[user.name]_1 TC_NS3_swm 
+** Expect 200 **
+Attrib TC_NS3_swm deleted from com.test.TC_NS3.@[THE_USER]_1
+
+# TC_NS3.50.8.POS Remove Permission
+as XX@NS
+perm ungrant com.att.aaf.attrib :com.att.*:TC_NS3_swm write com.test.TC_NS3.@[user.name]_1.admin
+** Expect 200 **
+UnGranted Permission [com.att.aaf.attrib|:com.att.*:TC_NS3_swm|write] from Role [com.test.TC_NS3.@[THE_USER]_1.admin]
+
+as testid_1@test.com
+# TC_NS3.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_NS3.@[user.name]_1
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_NS3.99.3.POS Print Namespaces
+ns list name com.test.TC_NS3.@[user.name]_1
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_NS3.@[THE_USER]_1]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NS3.99.10.POS Remove Special Permissions
+as XX@NS
+force perm delete com.att.aaf.attrib :com.att.*:TC_NS3_swm write
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.att.aaf.attrib :com.att.*:* read
+** Expect 200,404 **
+Deleted Permission
+
diff --git a/authz-test/TestSuite/expected/TC_NSdelete1.expected b/authz-test/TestSuite/expected/TC_NSdelete1.expected
new file mode 100644
index 0000000..29732c5
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_NSdelete1.expected
@@ -0,0 +1,362 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus@aaf.att.com boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_NSdelete1.10.0.POS Check for Existing Data
+ns list name com.test.TC_NSdelete1.@[user.name].app
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER].app]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.force.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.force.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+as XX@NS
+# TC_NSdelete1.10.1.POS Create Namespaces with valid IDs and Responsible Parties
+ns create com.test.TC_NSdelete1.@[user.name].app @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+ns create com.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+ns create com.test.force.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+ns create com.test.TC_NSdelete1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_NSdelete1.10.2.POS Expect Namespace to be created
+ns list name com.test.TC_NSdelete1.@[user.name].app 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER].app]
+--------------------------------------------------------------------------------
+com.test.TC_NSdelete1.@[THE_USER].app
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NSdelete1.@[THE_USER].app.admin                                  
+        com.test.TC_NSdelete1.@[THE_USER].app.owner                                  
+    Permissions
+        com.test.TC_NSdelete1.@[THE_USER].app.access *                        *              
+        com.test.TC_NSdelete1.@[THE_USER].app.access *                        read           
+
+ns list name com.test.TC_NSdelete1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NSdelete1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NSdelete1.@[THE_USER].admin                                      
+        com.test.TC_NSdelete1.@[THE_USER].owner                                      
+    Permissions
+        com.test.TC_NSdelete1.@[THE_USER].access *                        *              
+        com.test.TC_NSdelete1.@[THE_USER].access *                        read           
+
+ns list name com.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.@[THE_USER].admin                                                        
+        com.@[THE_USER].owner                                                        
+    Permissions
+        com.@[THE_USER].access              *                        *              
+        com.@[THE_USER].access              *                        read           
+
+ns list name com.test.force.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.force.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.force.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.force.@[THE_USER].admin                                             
+        com.test.force.@[THE_USER].owner                                             
+    Permissions
+        com.test.force.@[THE_USER].access   *                        *              
+        com.test.force.@[THE_USER].access   *                        read           
+
+# TC_NSdelete1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 201 **
+Created Role
+
+# TC_NSdelete1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_NSdelete1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_NSdelete1.10.12.POS Assign user for creating creds
+user role add testid@aaf.att.com com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_NSdelete1.@[THE_USER].cred_admin] to User [testid@aaf.att.com]
+
+as testid@aaf.att.com
+# TC_NSdelete1.20.1.POS Create valid Role in my Namespace
+role create com.test.TC_NSdelete1.@[user.name].app.r.A
+** Expect 201 **
+Created Role
+
+# TC_NSdelete1.20.2.POS Create valid permission 
+perm create com.test.TC_NSdelete1.@[user.name].app.p.A myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_NSdelete1.20.3.POS Add credential to my namespace
+user cred add m99990@app.@[user.name].TC_NSdelete1.test.com password123
+** Expect 201 **
+Added Credential [m99990@app.@[THE_USER].TC_NSdelete1.test.com]
+
+# TC_NSdelete1.20.10.NEG Delete Program Should fail because of attached credential
+ns delete com.test.TC_NSdelete1.@[user.name].app
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - [com.test.TC_NSdelete1.@[THE_USER].app] contains users, permissions, roles.
+  Delete dependencies and try again.  Note: using force=true will delete all. force=move will delete Creds, but move Roles and Perms to parent.
+
+# TC_NSdelete1.20.11.POS Delete Credential
+set force true
+user cred del m99990@app.@[user.name].TC_NSdelete1.test.com
+** Expect 200 **
+Deleted Credential [m99990@app.@[THE_USER].TC_NSdelete1.test.com]
+
+# TC_NSdelete1.20.12.NEG Delete Program with role and permission attached
+ns delete com.test.TC_NSdelete1.@[user.name].app
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - [com.test.TC_NSdelete1.@[THE_USER].app] contains permissions, roles.
+  Delete dependencies and try again.  Note: using force=true will delete all. force=move will delete Creds, but move Roles and Perms to parent.
+
+# TC_NSdelete1.20.20.POS Expect role and permission to move to parent ns
+set force move
+set force=move ns list name com.test.TC_NSdelete1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_NSdelete1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_NSdelete1.@[THE_USER].admin                                      
+        com.test.TC_NSdelete1.@[THE_USER].cred_admin                                 
+        com.test.TC_NSdelete1.@[THE_USER].owner                                      
+    Permissions
+        com.test.TC_NSdelete1.@[THE_USER].access *                        *              
+        com.test.TC_NSdelete1.@[THE_USER].access *                        read           
+
+as testid@aaf.att.com
+# TC_NSdelete1.30.1.POS Create valid Role in my Namespace
+role create com.@[user.name].r.A
+** Expect 201 **
+Created Role
+
+# TC_NSdelete1.30.2.NEG Delete Company with role attached
+ns delete com.@[user.name]
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - [com.@[THE_USER]] contains roles.
+  Delete dependencies and try again.  Note: using force=true will delete all. force=move will delete Creds, but move Roles and Perms to parent.
+
+# TC_NSdelete1.30.3.POS Namespace Admin can delete Namepace defined Roles
+role delete com.@[user.name].r.A
+** Expect 200 **
+Deleted Role
+
+# TC_NSdelete1.30.10.POS Create valid permission 
+perm create com.@[user.name].p.A myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_NSdelete1.30.11.NEG Delete Company with permission attached
+ns delete com.@[user.name]
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - [com.@[THE_USER]] contains permissions.
+  Delete dependencies and try again.  Note: using force=true will delete all. force=move will delete Creds, but move Roles and Perms to parent.
+
+# TC_NSdelete1.30.12.POS Namespace Admin can delete Namepace defined Perms
+perm delete com.@[user.name].p.A myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+# TC_NSdelete1.30.20.POS Create valid Credential in my namespace 
+user cred add m99990@@[user.name].com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].com]
+
+# TC_NSdelete1.30.21.NEG Delete Company with credential attached
+ns delete com.@[user.name]
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - [com.@[THE_USER]] contains users.
+  Delete dependencies and try again.  Note: using force=true will delete all. force=move will delete Creds, but move Roles and Perms to parent.
+
+# TC_NSdelete1.30.22.POS Namespace admin can remove Cred
+set force true
+user cred del m99990@@[user.name].com
+** Expect 200 **
+Deleted Credential [m99990@@[THE_USER].com]
+
+# TC_NSdelete1.30.30.POS Delete Company with no roles or perms attached
+ns delete com.@[user.name]
+** Expect 200 **
+Deleted Namespace
+
+# TC_NSdelete1.40.1.POS Create valid Role in my Namespace
+role create com.test.force.@[user.name].r.A
+** Expect 201 **
+Created Role
+
+# TC_NSdelete1.40.2.POS Create valid permission in my Namespace
+perm create com.test.force.@[user.name].p.A myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_NSdelete1.40.3.POS Add credential to my namespace
+user cred add m99990@@[user.name].force.test.com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].force.test.com]
+
+# TC_NSdelete1.40.10.POS Delete Program in my Namespace
+set force true
+set force=true ns delete com.test.force.@[user.name]
+** Expect 200 **
+Deleted Namespace
+
+sleep 0
+# TC_NSdelete1.40.20.NEG Role and permission should not exist
+ns list name com.test.force.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.force.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NSdelete1.40.22.NEG Credential should not exist
+set force true
+user cred del m99990@@[user.name].force.test.com
+** Expect 404 **
+Failed [SVC5404]: Not Found - Credential does not exist
+
+as testid@aaf.att.com
+# TC_NSdelete1.99.1.POS Namespace Admin can delete Namepace defined Roles
+role delete com.test.TC_NSdelete1.@[user.name].app.r.A
+** Expect 200,404 **
+Deleted Role
+
+# TC_NSdelete1.99.2.POS Namespace Admin can delete Namepace defined Roles
+perm delete com.test.TC_NSdelete1.@[user.name].app.p.A myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+# TC_NSdelete1.99.3.POS Namespace Admin can remove Namepace defined Credentials
+set force true
+set force=true user cred del m99990@@app.[user.name].TC_NSdelete1.test.com
+** Expect 200,404 **
+Failed [SVC5404]: Not Found - Credential does not exist
+
+# TC_NSdelete1.99.10.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 200,404 **
+Removed Role [com.test.TC_NSdelete1.@[THE_USER].cred_admin] from User [testid@aaf.att.com]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_NSdelete1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+set force true
+set force=true role delete com.test.TC_NSdelete1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_NSdelete1.99.97.POS Clean Namespace
+set force true
+set force=true ns delete com.test.TC_NSdelete1.@[user.name].app
+** Expect 200,404 **
+Deleted Namespace
+
+set force true
+set force=true ns delete com.test.TC_NSdelete1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+set force true
+set force=true ns delete com.test.force.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test.force.@[THE_USER] does not exist
+
+# TC_NSdelete1.99.98.POS Check Clean Namespace
+ns list name com.test.TC_NSdelete1.@[user.name].app
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER].app]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_NSdelete1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_NSdelete1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.force.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.force.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_NSdelete1.99.99.POS Clean and check Company Namespace
+as XX@NS
+set force true
+set force=true ns delete com.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.@[THE_USER] does not exist
+
+ns list name com.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_PW1.expected b/authz-test/TestSuite/expected/TC_PW1.expected
new file mode 100644
index 0000000..b167edb
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_PW1.expected
@@ -0,0 +1,170 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_PW1.10.0.POS Validate no NS
+ns list name com.test.TC_PW1.@[user.name] 
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_PW1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_PW1.10.1.POS Create Namespace to add IDs
+ns create com.test.TC_PW1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_PW1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_PW1.@[user.name].cred_admin
+** Expect 201 **
+Created Role
+
+as XX@NS
+# TC_PW1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_PW1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_PW1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_PW1.10.12.POS Assign user for creating creds
+user role add testid@aaf.att.com com.test.TC_PW1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_PW1.@[THE_USER].cred_admin] to User [testid@aaf.att.com]
+
+# TC_PW1.20.1.NEG ASPR 1010 Passwords must be at least 8 characters in length
+user cred add m12345@TC_PW1.test.com 12
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Password must be 8 chars or greater in length (ASPR-1010),
+Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.20.2.NEG ASPR 1010 Passwords must be at least 8 characters in length
+user cred add m12345@TC_PW1.test.com 1
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Password must be 8 chars or greater in length (ASPR-1010),
+Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.20.3.NEG ASPR 1010 Passwords must be at least 8 characters in length
+user cred add m12345@TC_PW1.test.com 1234567
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Password must be 8 chars or greater in length (ASPR-1010),
+Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.21.1.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com 12345678
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.21.2.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com abcdefgh
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.21.3.NEG ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#%^()*"
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Passwords must include characters from at least two of these groupings: alpha, numeric and one of these special chars: !@#$%^*()-+?/,:;. (ASPR-1010)
+
+# TC_PW1.21.4.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#a%^()*"
+** Expect 201 **
+Added Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+sleep 0
+user cred del m12345@@[user.name].TC_PW1.test.com
+** Expect 200 **
+Deleted Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+# TC_PW1.21.5.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com "!@#2%^()*"
+** Expect 201 **
+Added Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+sleep 0
+user cred del m12345@@[user.name].TC_PW1.test.com
+** Expect 200 **
+Deleted Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+# TC_PW1.21.6.POS ASPR 1010 Passwords must include chars from 2 groupings, alpha, numeric and special
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sd"
+** Expect 201 **
+Added Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+sleep 0
+user cred del m12345@@[user.name].TC_PW1.test.com
+** Expect 200 **
+Deleted Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+# TC_PW1.21.10.NEG ASPR 1010 Passwords cannot be the same as the User ID
+user cred add m12345@@[user.name].TC_PW1.test.com m12345
+** Expect 406 **
+Failed [SVC1406]: Not Acceptable - Password must be 8 chars or greater in length (ASPR-1010)
+
+# TC_PW1.23.1.NEG Too Few Args for User Cred 1
+user cred 
+** Expect -1 **
+Too few args: cred <add|del|reset|extend> <id> [password (! D|E)] [entry# (if multi)] 
+
+# TC_PW1.23.2.NEG Too Few Args for User Cred add
+user cred add
+** Expect -1 **
+Too few args: cred <add|del|reset|extend> <id> [password (! D|E)] [entry# (if multi)] 
+
+# TC_PW1.30.1.POS Create a Credential, with Temporary Time
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sd"
+** Expect 201 **
+Added Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+# TC_PW1.30.3.NEG Credential Exists
+user cred add m12345@@[user.name].TC_PW1.test.com "abc123sf"
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Credential with same Expiration Date exists, use 'reset'
+
+# TC_PW1.30.8.POS Reset this Password
+user cred reset m12345@@[user.name].TC_PW1.test.com "ABC123SD" 1
+** Expect 200 **
+Reset Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+# TC_PW1.30.9.POS Delete a Credential
+user cred del m12345@@[user.name].TC_PW1.test.com 1
+** Expect 200 **
+Deleted Credential [m12345@@[THE_USER].TC_PW1.test.com]
+
+as testid@aaf.att.com
+# TC_PW1.99.1.NEG Delete ID m12345@@[user.name].TC_PW1.test.com
+set force true
+user cred del m12345@@[user.name].TC_PW1.test.com
+** Expect 200,404 **
+Failed [SVC5404]: Not Found - Credential does not exist
+
+# TC_PW1.99.2.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_PW1.@[user.name].cred_admin
+** Expect 200,404 **
+Removed Role [com.test.TC_PW1.@[THE_USER].cred_admin] from User [testid@aaf.att.com]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_PW1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_PW1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+role delete com.test.TC_PW1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_PW1.99.98.POS Delete Namespace com..test.TC_PW1
+ns delete com.test.TC_PW1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_PW1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_PW1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_PW1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Perm1.expected b/authz-test/TestSuite/expected/TC_Perm1.expected
new file mode 100644
index 0000000..d099990
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Perm1.expected
@@ -0,0 +1,963 @@
+set testid <pass>
+set testid@aaf.att.com <pass>
+set XX@NS <pass>
+set testunused <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+# TC_Perm1.10.0.POS Validate Namespace is empty first
+as testid@aaf.att.com
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Perm1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_Perm1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Perm1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 201 **
+Created Role
+
+as XX@NS
+# TC_Perm1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_Perm1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_Perm1.10.12.POS Assign user for creating creds
+user role add XX@NS com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_Perm1.@[THE_USER].cred_admin] to User [XX@NS]
+
+# TC_Perm1.20.1.POS List Data on non-Empty NS
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+
+# TC_Perm1.20.2.POS Add Perm 
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Perm1.20.3.NEG Already Added Perm 
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Permission [com.test.TC_Perm1.@[THE_USER].p.A|myInstance|myAction] already exists.
+
+# TC_Perm1.20.4.POS Add Perm with non-existent Roles as well
+force perm create com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].r.A,com.test.TC_Perm1.@[user.name].r.B
+** Expect 201 **
+Created Role [com.test.TC_Perm1.@[THE_USER].r.A]
+Created Role [com.test.TC_Perm1.@[THE_USER].r.B]
+Created Permission
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.B|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.A]
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.B|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.B]
+
+# TC_Perm1.20.8.POS Print Info for Validation
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+
+# TC_Perm1.20.9.NEG Already Added Perm with some Roles as well
+perm create com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].r.A,com.test.TC_Perm1.@[user.name].r.B
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Permission [com.test.TC_Perm1.@[THE_USER].p.B|myInstance|myAction] already exists.
+
+# TC_Perm1.20.10.NEG Non-admins can't change description
+as testunused
+perm describe com.test.TC_Perm1.@[user.name].p.A myInstance myAction Description for A
+** Expect 403 **
+Failed [SVC1403]: Forbidden - You do not have approval to change Permission [com.test.TC_Perm1.@[THE_USER].p.A|myInstance|myAction]
+
+# TC_Perm1.20.11.NEG Permission must exist to change description
+as testid
+perm describe com.test.TC_Perm1.@[user.name].p.C myInstance myAction Description for C
+** Expect 404 **
+Failed [SVC1404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] does not exist
+
+# TC_Perm1.20.12.POS Admin can change description
+perm describe com.test.TC_Perm1.@[user.name].p.A myInstance myAction Description for A
+** Expect 200 **
+Description added to Permission
+
+# TC_Perm1.22.1.NEG Try to rename permission without changing anything
+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].p.B myInstance myAction
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - New Permission must be different than original permission
+
+# TC_Perm1.22.2.NEG Try to rename parent ns
+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.att.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - You do not have approval to change Permission [com.att.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.22.10.POS View permission in original state
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+
+# TC_Perm1.22.11.POS Rename permission instance
+perm rename com.test.TC_Perm1.@[user.name].p.B myInstance myAction com.test.TC_Perm1.@[user.name].p.B yourInstance myAction
+** Expect 200 **
+Updated Permission
+
+# TC_Perm1.22.12.POS Verify change in permission instance
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   yourInstance             myAction       
+
+# TC_Perm1.22.13.POS Rename permission action
+perm rename com.test.TC_Perm1.@[user.name].p.B yourInstance myAction com.test.TC_Perm1.@[user.name].p.B yourInstance yourAction
+** Expect 200 **
+Updated Permission
+
+# TC_Perm1.22.14.POS Verify change in permission action
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   yourInstance             yourAction     
+
+# TC_Perm1.22.15.POS Rename permission type
+perm rename com.test.TC_Perm1.@[user.name].p.B yourInstance yourAction com.test.TC_Perm1.@[user.name].p.yourB yourInstance yourAction
+** Expect 200 **
+Updated Permission
+
+# TC_Perm1.22.16.POS Verify change in permission type
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.yourB yourInstance             yourAction     
+
+# TC_Perm1.22.20.POS See permission is attached to this role
+role list role com.test.TC_Perm1.@[user.name].r.A
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Perm1.@[THE_USER].r.A]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER].r.A                      
+   com.test.TC_Perm1.@[THE_USER].p.yourB yourInstance                   yourAction     
+
+# TC_Perm1.22.21.POS Rename permission type, instance and action
+perm rename com.test.TC_Perm1.@[user.name].p.yourB yourInstance yourAction com.test.TC_Perm1.@[user.name].p.B myInstance myAction
+** Expect 200 **
+Updated Permission
+
+# TC_Perm1.22.22.POS See permission stays attached after rename
+role list role com.test.TC_Perm1.@[user.name].r.A
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Perm1.@[THE_USER].r.A]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER].r.A                      
+   com.test.TC_Perm1.@[THE_USER].p.B   myInstance                     myAction       
+
+# TC_Perm1.22.23.POS Verify permission is back to original state
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+
+# TC_Perm1.25.1.POS Create another Role in This namespace
+role create com.test.TC_Perm1.@[user.name].r.C
+** Expect 201 **
+Created Role
+
+# TC_Perm1.25.2.POS Create another Perm in This namespace
+perm create com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Perm1.25.3.NEG Permission must Exist to Add to Role
+perm grant com.test.TC_Perm1.@[user.name].p.NO myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.NO|myInstance|myAction] does not exist
+
+# TC_Perm1.25.4.POS Grant individual new Perm to new Role
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 201 **
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.25.5.NEG Already Granted Perm
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] already granted to Role [com.test.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.25.6.POS Print Info for Validation
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+        com.test.TC_Perm1.@[THE_USER].r.C                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.C   myInstance               myAction       
+
+# TC_Perm1.25.10.POS UnGrant individual new Perm to new Role
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 200 **
+UnGranted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] from Role [com.test.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.25.11.NEG Already UnGranted Perm
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] not associated with any Role
+
+# TC_Perm1.25.20.POS Reset roles attached to permision with setTo
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C,com.test.TC_Perm1.@[user.name].r.A
+** Expect 200 **
+Set Permission's Roles to [com.test.TC_Perm1.@[THE_USER].r.C,com.test.TC_Perm1.@[THE_USER].r.A]
+
+# TC_Perm1.25.21.POS Owner of permission can reset roles
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 200 **
+Set Permission's Roles to []
+
+# TC_Perm1.26.1.POS Create another Namespace, not owned by testid, one in company, one not
+as XX@NS
+ns create com.test2.TC_Perm1.@[user.name] @[user.name] XX@NS
+** Expect 201 **
+Created Namespace
+
+ns create com.test.TC_Perm1.@[user.name]_2 @[user.name] XX@NS
+** Expect 201 **
+Created Namespace
+
+# TC_Perm1.26.2.POS Create ID in other Namespace
+user cred add m99990@@[user.name].TC_Perm1.test2.com aRealPass7
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_Perm1.test2.com]
+
+# TC_Perm1.26.3.POS Create a Role in other Namespaces, not owned by testid
+role create com.test2.TC_Perm1.@[user.name].r.C
+** Expect 201 **
+Created Role
+
+role create com.test2.TC_Perm1.@[user.name]_2.r.C
+** Expect 201 **
+Created Role
+
+# TC_Perm1.26.11.NEG Grant Perm to Role in Other Namespace, when Role ID
+as m99990@@[THE_USER].TC_Perm1.test2.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.11a.NEG Grant Perm to Role in Other Namespace, when Role ID
+as m99990@@[THE_USER].TC_Perm1.test2.com
+set request true
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Perm1.26.12.NEG Grant Perm to Role in Other Namespace, when Perm ID, but different Company
+as testid@aaf.att.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid@aaf.att.com] may not write Role [com.test2.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.26.13.NEG Fail Grant Perm to Role in Other Namespace, when Perm ID, but same Company
+as testid@aaf.att.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Perm1.@[THE_USER]_2.r.C] does not exist
+
+# TC_Perm1.26.14.POS Create Role
+as testid@aaf.att.com
+role create com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 201 **
+Created Role
+
+# TC_Perm1.26.15.POS Fail Create/Grant Perm to Role in Other Namespace, when Perm ID, but same Company
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 201 **
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER]_2.r.C]
+
+# TC_Perm1.26.16.POS Print Info for Validation
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+        com.test.TC_Perm1.@[THE_USER].r.C                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.C   myInstance               myAction       
+
+# TC_Perm1.26.17.POS Grant individual new Perm to new Role
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 201 **
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.26.18.NEG Already Granted Perm
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] already granted to Role [com.test.TC_Perm1.@[THE_USER].r.C]
+
+# TC_Perm1.26.19.POS UnGrant Perm from Role in Other Namespace, when Perm ID
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 200 **
+UnGranted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] from Role [com.test.TC_Perm1.@[THE_USER]_2.r.C]
+
+# TC_Perm1.26.21.NEG No Permission to Grant Perm to Role with Unrelated ID
+as m99990@@[THE_USER].TC_Perm1.test2.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.22.NEG No Permission to Grant Perm to Role with Unrelated ID
+set request true
+as m99990@@[THE_USER].TC_Perm1.test2.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Perm1.26.25.NEG No Permission to UnGrant with Unrelated ID
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.B
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.26.NEG No Permission to UnGrant with Unrelated ID
+set request true
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.B
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Perm1.26.30.POS  Add ID to Role
+as XX@NS
+ns admin add com.test2.TC_Perm1.@[user.name] m99990@@[user.name].TC_Perm1.test2.com 
+** Expect 201 **
+Admin m99990@@[THE_USER].TC_Perm1.test2.com added to com.test2.TC_Perm1.@[THE_USER]
+
+as m99990@@[THE_USER].TC_Perm1.test2.com
+sleep 0
+# TC_Perm1.26.31.NEG No Permission Grant Perm to Role if not Perm Owner
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.31.NEG No Permission Grant Perm to Role if not Perm Owner
+set request true
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test2.TC_Perm1.@[user.name].r.C
+** Expect 202 **
+Permission Role Granted Accepted, but requires Approvals before actualizing
+
+# TC_Perm1.26.32.POS Grant individual new Perm to Role in Other Namespace
+as testid@aaf.att.com
+perm grant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 201 **
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER]_2.r.C]
+
+# TC_Perm1.26.34.POS Print Info for Validation
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+        com.test.TC_Perm1.@[THE_USER].r.C                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.C   myInstance               myAction       
+
+as XX@NS
+# TC_Perm1.26.35.POS Print Info for Validation
+ns list name com.test2.TC_Perm1.@[user.name]  
+** Expect 200 **
+
+List Namespaces by Name[com.test2.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test2.TC_Perm1.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+        m99990@@[THE_USER].TC_Perm1.test2.com                                        
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test2.TC_Perm1.@[THE_USER].admin                                         
+        com.test2.TC_Perm1.@[THE_USER].owner                                         
+        com.test2.TC_Perm1.@[THE_USER].r.C                                           
+    Permissions
+        com.test2.TC_Perm1.@[THE_USER].access *                        *              
+        com.test2.TC_Perm1.@[THE_USER].access *                        read           
+    Credentials
+        m99990@@[THE_USER].TC_Perm1.test2.com                                        
+
+as testid@aaf.att.com
+# TC_Perm1.26.36.POS UnGrant individual new Perm to new Role
+as testid@aaf.att.com
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 200 **
+UnGranted Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] from Role [com.test.TC_Perm1.@[THE_USER]_2.r.C]
+
+# TC_Perm1.26.37.NEG Already UnGranted Perm
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] not associated with any Role
+
+# TC_Perm1.26.40.POS Reset roles attached to permision with setTo
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C,com.test.TC_Perm1.@[user.name].r.A
+** Expect 200 **
+Set Permission's Roles to [com.test.TC_Perm1.@[THE_USER].r.C,com.test.TC_Perm1.@[THE_USER].r.A]
+
+# TC_Perm1.26.41.NEG Non-owner of permission cannot reset roles
+as m99990@@[THE_USER].TC_Perm1.test2.com
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.42.NEG Non-owner of permission cannot ungrant
+perm ungrant com.test.TC_Perm1.@[user.name].p.C myInstance myAction com.test.TC_Perm1.@[user.name].r.C
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.43.NEG Non-owner of permission cannot delete
+perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_Perm1.test2.com] may not write Perm [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction]
+
+# TC_Perm1.26.45.POS Owner of permission can reset roles
+as testid@aaf.att.com
+perm setTo com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 200 **
+Set Permission's Roles to []
+
+as XX@NS
+# TC_Perm1.26.97.POS List the Namespaces 
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.B                                            
+        com.test.TC_Perm1.@[THE_USER].r.C                                            
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.B   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.C   myInstance               myAction       
+
+ns list name com.test2.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test2.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test2.TC_Perm1.@[THE_USER]
+    Administrators
+        XX@NS                                                      
+        m99990@@[THE_USER].TC_Perm1.test2.com                                        
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test2.TC_Perm1.@[THE_USER].admin                                         
+        com.test2.TC_Perm1.@[THE_USER].owner                                         
+        com.test2.TC_Perm1.@[THE_USER].r.C                                           
+    Permissions
+        com.test2.TC_Perm1.@[THE_USER].access *                        *              
+        com.test2.TC_Perm1.@[THE_USER].access *                        read           
+    Credentials
+        m99990@@[THE_USER].TC_Perm1.test2.com                                        
+
+as testid@aaf.att.com
+# TC_Perm1.26.98.POS Cleanup
+role delete com.test.TC_Perm1.@[user.name].r.A
+** Expect 200 **
+Deleted Role
+
+role delete com.test.TC_Perm1.@[user.name].r.B
+** Expect 200 **
+Deleted Role
+
+role delete com.test.TC_Perm1.@[user.name].r.C
+** Expect 200 **
+Deleted Role
+
+role delete com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 200 **
+Deleted Role
+
+as XX@NS
+role delete com.test2.TC_Perm1.@[user.name]_2.r.C
+** Expect 200 **
+Deleted Role
+
+role delete com.test2.TC_Perm1.@[user.name].r.C
+** Expect 200 **
+Deleted Role
+
+as testid@aaf.att.com
+perm delete com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+perm delete com.test.TC_Perm1.@[user.name].p.B myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+force ns delete com.test.TC_Perm1.@[user.name]_2
+** Expect 200 **
+Deleted Namespace
+
+as XX@NS
+set force true
+set force=true user cred del m99990@@[user.name].TC_Perm1.test2.com 
+** Expect 200 **
+Deleted Credential [m99990@@[THE_USER].TC_Perm1.test2.com]
+
+ns delete com.test2.TC_Perm1.@[user.name]
+** Expect 200 **
+Deleted Namespace
+
+# TC_Perm1.26.99.POS List the Now Empty Namespaces 
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+
+ns list name com.test2.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test2.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Perm1.27.1.POS Create Permission
+perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction 
+** Expect 201 **
+Created Permission
+
+# TC_Perm1.27.2.POS Create Role
+role create com.test.TC_Perm1.@[user.name].r.A
+** Expect 201 **
+Created Role
+
+# TC_Perm1.27.10.NEG Role must Exist to Add to Role without force
+perm grant com.test.TC_Perm1.@[user.name].p.A myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown
+** Expect 404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Perm1.@[THE_USER].r.unknown] does not exist
+
+# TC_Perm1.27.11.POS Role is created with force
+force perm create com.test.TC_Perm1.@[user.name].p.A myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown
+** Expect 201 **
+Created Role [com.test.TC_Perm1.@[THE_USER].r.unknown]
+Created Permission
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.A|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.unknown]
+
+# TC_Perm1.27.12.NEG Perm must Exist to Grant without force
+perm grant com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction com.test.TC_Perm1.@[user.name].r.A
+** Expect 404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.unknown|myInstance|myAction] does not exist
+
+# TC_Perm1.27.13.POS Perm is created with force
+force perm grant com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction com.test.TC_Perm1.@[user.name].r.A
+** Expect 201 **
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.unknown|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.A]
+
+# TC_Perm1.27.14.POS Role and perm are created with force
+force perm create com.test.TC_Perm1.@[user.name].p.unknown2 myInstance myAction com.test.TC_Perm1.@[user.name].r.unknown2
+** Expect 201 **
+Created Role [com.test.TC_Perm1.@[THE_USER].r.unknown2]
+Created Permission
+Granted Permission [com.test.TC_Perm1.@[THE_USER].p.unknown2|myInstance|myAction] to Role [com.test.TC_Perm1.@[THE_USER].r.unknown2]
+
+# TC_Perm1.30.1.POS List Data on non-Empty NS
+as testid
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.unknown                                      
+        com.test.TC_Perm1.@[THE_USER].r.unknown2                                     
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.unknown myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.unknown2 myInstance               myAction       
+
+# TC_Perm1.30.2.POS Create Sub-ns when Roles that exist
+ns create com.test.TC_Perm1.@[user.name].r @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Perm1.30.3.POS List Data on NS with sub-roles
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].admin                                          
+        com.test.TC_Perm1.@[THE_USER].cred_admin                                     
+        com.test.TC_Perm1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].access *                        *              
+        com.test.TC_Perm1.@[THE_USER].access *                        read           
+        com.test.TC_Perm1.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.unknown myInstance               myAction       
+        com.test.TC_Perm1.@[THE_USER].p.unknown2 myInstance               myAction       
+
+ns list name com.test.TC_Perm1.@[user.name].r
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER].r]
+--------------------------------------------------------------------------------
+com.test.TC_Perm1.@[THE_USER].r
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm1.@[THE_USER].r.A                                            
+        com.test.TC_Perm1.@[THE_USER].r.admin                                        
+        com.test.TC_Perm1.@[THE_USER].r.owner                                        
+        com.test.TC_Perm1.@[THE_USER].r.unknown                                      
+        com.test.TC_Perm1.@[THE_USER].r.unknown2                                     
+    Permissions
+        com.test.TC_Perm1.@[THE_USER].r.access *                        *              
+        com.test.TC_Perm1.@[THE_USER].r.access *                        read           
+
+as XX@NS
+# TC_Perm1.99.1.POS Namespace Admin can delete Namepace defined Roles
+set force true
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.A myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+set force true
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.B myInstance myAction
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.B|myInstance|myAction] does not exist
+
+set force true
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.C myInstance myAction
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.test.TC_Perm1.@[THE_USER].p.C|myInstance|myAction] does not exist
+
+set force true
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.unknown myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+set force true
+set force=true perm delete com.test.TC_Perm1.@[user.name].p.unknown2 myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+role delete com.test.TC_Perm1.@[user.name].r.A
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test.TC_Perm1.@[user.name].r.B
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Perm1.@[THE_USER].r.B] does not exist
+
+role delete com.test.TC_Perm1.@[user.name].r.C
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Perm1.@[THE_USER].r.C] does not exist
+
+role delete com.test.TC_Perm1.@[user.name].r.unknown
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test.TC_Perm1.@[user.name].r.unknown2
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test2.TC_Perm1.@[user.name].r.C
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test2.TC_Perm1.@[THE_USER].r.C] does not exist
+
+role delete com.test.TC_Perm1.@[user.name]_2.r.C
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Perm1.@[THE_USER]_2.r.C] does not exist
+
+role delete com.test2.TC_Perm1.@[user.name]_2.r.C
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test2.TC_Perm1.@[THE_USER]_2.r.C] does not exist
+
+# TC_Perm1.99.2.POS Remove ability to create creds
+user role del XX@NS com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 200,404 **
+Removed Role [com.test.TC_Perm1.@[THE_USER].cred_admin] from User [XX@NS]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_Perm1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+role delete com.test.TC_Perm1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+sleep 0
+as XX@NS
+# TC_Perm1.99.98.POS Namespace Admin can delete Namespace
+set force true
+set force=true ns delete com.test2.TC_Perm1.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test2.TC_Perm1.@[THE_USER] does not exist
+
+as testid
+force ns delete com.test.TC_Perm1.@[user.name].r
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test.TC_Perm1.@[user.name]_2
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test.TC_Perm1.@[THE_USER]_2 does not exist
+
+force ns delete com.test.TC_Perm1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test2.TC_Perm1.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test2.TC_Perm1.@[THE_USER] does not exist
+
+# TC_Perm1.99.99.POS List to prove removed
+ns list name com.test.TC_Perm1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Perm1.@[user.name].r
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER].r]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Perm1.@[user.name]_2
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm1.@[THE_USER]_2]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test2.TC_Perm1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test2.TC_Perm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Perm2.expected b/authz-test/TestSuite/expected/TC_Perm2.expected
new file mode 100644
index 0000000..dadff03
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Perm2.expected
@@ -0,0 +1,554 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Perm2.10.0.POS Print NS to prove ok
+ns list name com.test.TC_Perm2.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Perm2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_Perm2.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+as testid@aaf.att.com
+# TC_Perm2.20.1.POS List Data on non-Empty NS
+ns list name com.test.TC_Perm2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm2.@[THE_USER].admin                                          
+        com.test.TC_Perm2.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Perm2.@[THE_USER].access *                        *              
+        com.test.TC_Perm2.@[THE_USER].access *                        read           
+
+# TC_Perm2.20.10.POS Add Perms with specific Instance and Action
+perm create com.test.TC_Perm2.@[user.name].p.A myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Perm2.20.11.POS Add Perms with specific Instance and Star
+perm create com.test.TC_Perm2.@[user.name].p.A myInstance *
+** Expect 201 **
+Created Permission
+
+# TC_Perm2.20.12.POS Add Perms with Stars for Instance and Action
+perm create com.test.TC_Perm2.@[user.name].p.A * *
+** Expect 201 **
+Created Permission
+
+perm create com.test.TC_Perm2.@[user.name].p.phoneCalls * spy
+** Expect 201 **
+Created Permission
+
+# TC_Perm2.20.20.POS Create role 
+role create com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Created Role
+
+role create com.test.TC_Perm2.@[user.name].p.secret
+** Expect 201 **
+Created Role
+
+# TC_Perm2.20.21.POS Grant sub-NS perms to role
+perm grant com.test.TC_Perm2.@[user.name].p.A myInstance myAction com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Granted Permission [com.test.TC_Perm2.@[THE_USER].p.A|myInstance|myAction] to Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+
+perm grant com.test.TC_Perm2.@[user.name].p.A myInstance * com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Granted Permission [com.test.TC_Perm2.@[THE_USER].p.A|myInstance|*] to Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+
+perm grant com.test.TC_Perm2.@[user.name].p.A * * com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Granted Permission [com.test.TC_Perm2.@[THE_USER].p.A|*|*] to Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+
+perm grant com.test.TC_Perm2.@[user.name].p.phoneCalls * spy com.test.TC_Perm2.@[user.name].p.secret
+** Expect 201 **
+Granted Permission [com.test.TC_Perm2.@[THE_USER].p.phoneCalls|*|spy] to Role [com.test.TC_Perm2.@[THE_USER].p.secret]
+
+# TC_Perm2.20.30.POS List Data on non-Empty NS
+ns list name com.test.TC_Perm2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm2.@[THE_USER].admin                                          
+        com.test.TC_Perm2.@[THE_USER].owner                                          
+        com.test.TC_Perm2.@[THE_USER].p.secret                                       
+        com.test.TC_Perm2.@[THE_USER].p.superUser                                    
+    Permissions
+        com.test.TC_Perm2.@[THE_USER].access *                        *              
+        com.test.TC_Perm2.@[THE_USER].access *                        read           
+        com.test.TC_Perm2.@[THE_USER].p.A   *                        *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm2.@[THE_USER].p.phoneCalls *                        spy            
+
+# TC_Perm2.20.40.POS Create role
+role create com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 201 **
+Created Role
+
+as XX@NS
+# TC_Perm2.20.50.POS Grant view perms to watcher role
+perm create com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:myInstance:myAction view com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.perm|:com.test.TC_Perm2.@[THE_USER].p.A:myInstance:myAction|view] to Role [com.test.TC_Perm2.@[THE_USER].p.watcher]
+
+perm create com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.perm|:com.test.TC_Perm2.@[THE_USER].p.A:*:*|view] to Role [com.test.TC_Perm2.@[THE_USER].p.watcher]
+
+as testid@aaf.att.com
+# TC_Perm2.30.1.POS List Data on non-Empty NS
+ns list name com.test.TC_Perm2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm2.@[THE_USER].admin                                          
+        com.test.TC_Perm2.@[THE_USER].owner                                          
+        com.test.TC_Perm2.@[THE_USER].p.secret                                       
+        com.test.TC_Perm2.@[THE_USER].p.superUser                                    
+        com.test.TC_Perm2.@[THE_USER].p.watcher                                      
+    Permissions
+        com.test.TC_Perm2.@[THE_USER].access *                        *              
+        com.test.TC_Perm2.@[THE_USER].access *                        read           
+        com.test.TC_Perm2.@[THE_USER].p.A   *                        *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm2.@[THE_USER].p.phoneCalls *                        spy            
+
+# TC_Perm2.30.2.POS Create Sub-ns when Roles that exist
+ns create com.test.TC_Perm2.@[user.name].p @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Perm2.30.3.POS List Data on NS with sub-roles
+ns list name com.test.TC_Perm2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm2.@[THE_USER].admin                                          
+        com.test.TC_Perm2.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Perm2.@[THE_USER].access *                        *              
+        com.test.TC_Perm2.@[THE_USER].access *                        read           
+
+ns list name com.test.TC_Perm2.@[user.name].p
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER].p]
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Perm2.@[THE_USER].p.admin                                        
+        com.test.TC_Perm2.@[THE_USER].p.owner                                        
+        com.test.TC_Perm2.@[THE_USER].p.secret                                       
+        com.test.TC_Perm2.@[THE_USER].p.superUser                                    
+        com.test.TC_Perm2.@[THE_USER].p.watcher                                      
+    Permissions
+        com.test.TC_Perm2.@[THE_USER].p.A   *                        *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               *              
+        com.test.TC_Perm2.@[THE_USER].p.A   myInstance               myAction       
+        com.test.TC_Perm2.@[THE_USER].p.access *                        *              
+        com.test.TC_Perm2.@[THE_USER].p.access *                        read           
+        com.test.TC_Perm2.@[THE_USER].p.phoneCalls *                        spy            
+
+as testunused@aaf.att.com
+# TC_Perm2.40.1.NEG Non-admin, not granted user should not view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+as testid@aaf.att.com
+# Tens test user granted to permission
+# TC_Perm2.40.10.POS Add user to superUser role
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Added Role [com.test.TC_Perm2.@[THE_USER].p.superUser] to User [testunused@aaf.att.com]
+
+as testunused@aaf.att.com
+# TC_Perm2.40.11.POS Non-admin, granted user should view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   *                              *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+as testid@aaf.att.com
+# TC_Perm2.40.12.POS Ungrant perm with wildcards
+perm ungrant com.test.TC_Perm2.@[user.name].p.A * * com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 200 **
+UnGranted Permission [com.test.TC_Perm2.@[THE_USER].p.A|*|*] from Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+
+as testunused@aaf.att.com
+# TC_Perm2.40.13.POS Non-admin, granted user should view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+as testid@aaf.att.com
+# TC_Perm2.40.19.POS Remove user from superUser role
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 200 **
+Removed Role [com.test.TC_Perm2.@[THE_USER].p.superUser] from User [testunused@aaf.att.com]
+
+# Twenties test user granted explicit view permission
+# TC_Perm2.40.20.POS Add user to watcher role
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 201 **
+Added Role [com.test.TC_Perm2.@[THE_USER].p.watcher] to User [testunused@aaf.att.com]
+
+as testunused@aaf.att.com
+# TC_Perm2.40.21.NEG Non-admin, granted explicit view perm user should view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+as XX@NS
+# TC_Perm2.40.22.POS Ungrant perm with wildcards
+perm ungrant com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 200 **
+UnGranted Permission [com.att.aaf.perm|:com.test.TC_Perm2.@[THE_USER].p.A:*:*|view] from Role [com.test.TC_Perm2.@[THE_USER].p.watcher]
+
+as testunused@aaf.att.com
+# TC_Perm2.40.23.POS Non-admin, granted user should view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+as testid@aaf.att.com
+# TC_Perm2.40.29.POS Remove user from watcher role
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 200 **
+Removed Role [com.test.TC_Perm2.@[THE_USER].p.watcher] from User [testunused@aaf.att.com]
+
+# Thirties test admin user 
+# TC_Perm2.40.30.POS Admin should be able to view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   *                              *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+# TC_Perm2.40.31.POS Add new admin for sub-NS
+ns admin add com.test.TC_Perm2.@[user.name].p testunused@aaf.att.com
+** Expect 201 **
+Admin testunused@aaf.att.com added to com.test.TC_Perm2.@[THE_USER].p
+
+# TC_Perm2.40.32.POS Remove admin from sub-NS
+ns admin del com.test.TC_Perm2.@[user.name].p testid@aaf.att.com
+** Expect 200 **
+Admin testid@aaf.att.com deleted from com.test.TC_Perm2.@[THE_USER].p
+
+# TC_Perm2.40.34.POS Admin of parent NS should be able to view
+perm list name com.test.TC_Perm2.@[user.name].p.A
+** Expect 200 **
+
+List Child Permissions[com.test.TC_Perm2.@[THE_USER].p.A]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   *                              *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+# TC_Perm2.40.80.POS Add new admin for sub-NS
+ns admin add com.test.TC_Perm2.@[user.name].p testid@aaf.att.com
+** Expect 201 **
+Admin testid@aaf.att.com added to com.test.TC_Perm2.@[THE_USER].p
+
+# TC_Perm2.40.81.POS Remove admin from sub-NS
+ns admin del com.test.TC_Perm2.@[user.name].p testunused@aaf.att.com
+** Expect 200 **
+Admin testunused@aaf.att.com deleted from com.test.TC_Perm2.@[THE_USER].p
+
+# TC_Perm2.41.1.POS Add user to some roles with perms attached
+as testid@aaf.att.com
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 201 **
+Added Role [com.test.TC_Perm2.@[THE_USER].p.superUser] to User [testunused@aaf.att.com]
+
+user role add testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 201 **
+Added Role [com.test.TC_Perm2.@[THE_USER].p.watcher] to User [testunused@aaf.att.com]
+
+user role add XX@NS com.test.TC_Perm2.@[user.name].p.secret
+** Expect 201 **
+Added Role [com.test.TC_Perm2.@[THE_USER].p.secret] to User [XX@NS]
+
+# TC_Perm2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+perm list user testunused@aaf.att.com
+** Expect 200 **
+
+List Permissions by User[testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.aaf.perm               :com.test.TC_Perm2.@[THE_USER].p.A:myInstance:myAction view      
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+# TC_NS2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+perm list user testunused@aaf.att.com
+** Expect 200 **
+
+List Permissions by User[testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+# TC_Perm2.41.20.POS List by User when not same as Caller, but parent owner/admin of Namespace
+as XX@NS
+perm list user testunused@aaf.att.com
+** Expect 200 **
+
+List Permissions by User[testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.aaf.perm               :com.test.TC_Perm2.@[THE_USER].p.A:myInstance:myAction view      
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+# TC_Perm2.41.80.NEG List by User when not Caller nor associated to Namespace (nothing should be shown)
+as testunused@aaf.att.com
+perm list user XX@NS
+** Expect 200 **
+
+List Permissions by User[XX@NS]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+# TC_Perm2.41.99.POS Remove users from roles for later test
+as testid@aaf.att.com
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 200 **
+Removed Role [com.test.TC_Perm2.@[THE_USER].p.superUser] from User [testunused@aaf.att.com]
+
+user role del testunused@aaf.att.com com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 200 **
+Removed Role [com.test.TC_Perm2.@[THE_USER].p.watcher] from User [testunused@aaf.att.com]
+
+user role del XX@NS com.test.TC_Perm2.@[user.name].p.secret
+** Expect 200 **
+Removed Role [com.test.TC_Perm2.@[THE_USER].p.secret] from User [XX@NS]
+
+# TC_Perm2.42.10.POS List Roles from NS when not allowed to see NS
+as testid@aaf.att.com
+perm list ns com.test.TC_Perm2.@[user.name].p
+** Expect 200 **
+
+List Perms by NS [com.test.TC_Perm2.@[THE_USER].p]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   *                              *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+com.test.TC_Perm2.@[THE_USER].p.access *                              *         
+com.test.TC_Perm2.@[THE_USER].p.access *                              read      
+com.test.TC_Perm2.@[THE_USER].p.phoneCalls *                              spy       
+
+
+# TC_Perm2.42.20.NEG Don't List Roles from NS when not allowed to see NS
+as testunused@aaf.att.com
+perm list ns com.test.TC_Perm2.@[user.name].p
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read in NS [com.test.TC_Perm2.@[THE_USER].p]
+
+# TC_Perm2.43.10.POS List perms when allowed to see Role
+as testid@aaf.att.com
+perm list role com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     *         
+com.test.TC_Perm2.@[THE_USER].p.A   myInstance                     myAction  
+
+
+perm list role com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Perm2.@[THE_USER].p.watcher]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+
+
+perm list role com.test.TC_Perm2.@[user.name].p.secret
+** Expect 200 **
+
+List Perms by Role [com.test.TC_Perm2.@[THE_USER].p.secret]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.test.TC_Perm2.@[THE_USER].p.phoneCalls *                              spy       
+
+
+# TC_Perm2.43.20.NEG Don't List perms when not allowed to see Role
+as testunused@aaf.att.com
+perm list role com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Perm2.@[THE_USER].p.superUser]
+
+perm list role com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Perm2.@[THE_USER].p.watcher]
+
+perm list role com.test.TC_Perm2.@[user.name].p.secret
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Perm2.@[THE_USER].p.secret]
+
+as testid@aaf.att.com
+# TC_Perm2.99.1.POS Namespace Admin can delete Namepace defined Roles
+force perm delete com.test.TC_Perm2.@[user.name].p.A myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Perm2.@[user.name].p.A myInstance *
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Perm2.@[user.name].p.A * *
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Perm2.@[user.name].p.phoneCalls * spy
+** Expect 200,404 **
+Deleted Permission
+
+force role delete com.test.TC_Perm2.@[user.name].p.watcher
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Perm2.@[user.name].p.superUser
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Perm2.@[user.name].p.secret
+** Expect 200,404 **
+Deleted Role
+
+as XX@NS
+force perm delete com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:*:* view
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.att.aaf.perm :com.test.TC_Perm2.@[user.name].p.A:myInstance:myAction view
+** Expect 200,404 **
+Deleted Permission
+
+# TC_Perm2.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Perm2.@[user.name].p
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test.TC_Perm2.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Perm2.99.3.POS Print Namespaces
+ns list name com.test.TC_Perm2.@[user.name].p
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER].p]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Perm2.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Perm3.expected b/authz-test/TestSuite/expected/TC_Perm3.expected
new file mode 100644
index 0000000..6cdf229
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Perm3.expected
@@ -0,0 +1,136 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set testid_1@test.com <pass>
+set testid_2@test.com <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as XX@NS
+# TC_Perm3.10.0.POS Print NS to prove ok
+ns list name com.test.TC_Perm3.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Perm3.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Perm3.10.1.POS Create Namespace with User ID
+ns create com.test.TC_Perm3.@[user.name]_1 @[user.name] testid_1@test.com
+** Expect 201 **
+Created Namespace
+
+# TC_Perm3.10.2.POS Create Namespace with Different ID
+ns create com.test.TC_Perm3.@[user.name]_2 @[user.name] testid_2@test.com
+** Expect 201 **
+Created Namespace
+
+# TC_Perm3.10.3.POS Create Namespace in Different Company
+ns create com.att.TC_Perm3.@[user.name] @[user.name] testunused@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+as testid_1@test.com
+# TC_Perm3.20.0.POS User1 Create a Perm
+perm create com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Perm3.20.5.NEG User1 should not be able to create Role in other group
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid_1@test.com] may not write Role [com.test.TC_Perm3.@[THE_USER]_2.dev.myRole_a]
+
+# TC_Perm3.20.6.POS User2 should be able to create Role in own group
+as testid_2@test.com
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+** Expect 201 **
+Created Role
+
+# TC_Perm3.20.7.NEG User2 should not be able to grant Perm to own Role
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid_2@test.com] may not write Perm [com.test.TC_Perm3.@[THE_USER]_1.dev.myPerm_a|myInstance|myAction]
+
+# TC_Perm3.20.8.NEG User2 cannot create Role in NS 2
+as testid_2@test.com
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid_2@test.com] may not write Perm [com.test.TC_Perm3.@[THE_USER]_1.dev.myPerm_a|myInstance|myAction]
+
+# TC_Perm3.20.9.POS Role created, but can't grant... has to be testid_1
+as testid_1@test.com
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_a myInstance myAction com.test.TC_Perm3.@[user.name]_2.dev.myRole_a
+** Expect 201 **
+Granted Permission [com.test.TC_Perm3.@[THE_USER]_1.dev.myPerm_a|myInstance|myAction] to Role [com.test.TC_Perm3.@[THE_USER]_2.dev.myRole_a]
+
+# TC_Perm3.30.0.POS User1 Create a Perm
+as testid_1@test.com
+perm create com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Perm3.30.5.NEG User1 should not be able to create Role in other group
+role create com.test.TC_Perm3.@[user.name]_2.dev.myRole_b
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid_1@test.com] may not write Role [com.test.TC_Perm3.@[THE_USER]_2.dev.myRole_b]
+
+# TC_Perm3.30.6.POS User2 should be able to create Role in own group
+as testunused@aaf.att.com
+role create com.att.TC_Perm3.@[user.name].dev.myRole_b
+** Expect 201 **
+Created Role
+
+# TC_Perm3.30.7.NEG User2 should not be able to grant Perm to own Role
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction com.att.TC_Perm3.@[user.name].dev.myRole_b
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not write Perm [com.test.TC_Perm3.@[THE_USER]_1.dev.myPerm_b|myInstance|myAction]
+
+# TC_Perm3.30.8.POS User should be able to grant cross company only Double Perm
+as testid_1@test.com
+perm grant com.test.TC_Perm3.@[user.name]_1.dev.myPerm_b myInstance myAction com.att.TC_Perm3.@[user.name].dev.myRole_b
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testid_1@test.com] may not write Role [com.att.TC_Perm3.@[THE_USER].dev.myRole_b]
+
+as testid_1@test.com
+# TC_Perm3.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Perm3.@[user.name]_1
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Perm3.99.3.POS Print Namespaces
+ns list name com.test.TC_Perm3.@[user.name]_1
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm3.@[THE_USER]_1]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+as testid_2@test.com
+# TC_Perm3.99.4.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Perm3.@[user.name]_2
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Perm3.99.5.POS Print Namespaces
+ns list name com.test.TC_Perm3.@[user.name]_2
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Perm3.@[THE_USER]_2]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+as testunused@aaf.att.com
+# TC_Perm3.99.6.POS Remove Namespace from other company
+force ns delete com.att.TC_Perm3.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Perm3.99.7.POS Print Namespace from other company
+ns list name com.att.TC_Perm3.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.att.TC_Perm3.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Realm1.expected b/authz-test/TestSuite/expected/TC_Realm1.expected
new file mode 100644
index 0000000..67232e2
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Realm1.expected
@@ -0,0 +1,210 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Realm1.10.0.POS Validate no NS
+ns list name com.test.TC_Realm1.@[user.name] 
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Realm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Realm1.10.1.POS Create Namespace to add IDs
+ns create com.test.TC_Realm1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+as XX@NS
+# TC_Realm1.10.10.POS Grant ability to change delegates
+force perm create com.att.aaf.delg com.att create com.test.TC_Realm1.@[user.name].change_delg
+** Expect 201 **
+Created Role [com.test.TC_Realm1.@[THE_USER].change_delg]
+Created Permission
+Granted Permission [com.att.aaf.delg|com.att|create] to Role [com.test.TC_Realm1.@[THE_USER].change_delg]
+
+# TC_Realm1.10.11.POS Create user role to change delegates
+user role add testid@aaf.att.com com.test.TC_Realm1.@[user.name].change_delg
+** Expect 201 **
+Added Role [com.test.TC_Realm1.@[THE_USER].change_delg] to User [testid@aaf.att.com]
+
+as testid@aaf.att.com
+# TC_Realm1.20.1.NEG Fail to create - default domain wrong
+ns create com.test.TC_Realm1.@[user.name].project1 testunused
+** Expect 403 **
+Failed [SVC3403]: Forbidden - testunused@csp.att.com does not have permission to assume test status at AT&T
+
+# TC_Realm1.20.2.POS Create - default domain appended
+ns create com.test.TC_Realm1.@[user.name].project1 @[user.name] @[user.name]
+** Expect 201 **
+Created Namespace
+
+# TC_Realm1.20.3.NEG Fail to create - default domain wrong
+ns admin add com.test.TC_Realm1.@[user.name].project1 testunused
+** Expect 403 **
+Failed [SVC1403]: Forbidden - AT&T reports that testunused@csp.att.com is a faulty ID
+
+# TC_Realm1.20.4.POS Create - full domain given
+ns admin add com.test.TC_Realm1.@[user.name].project1 testid@aaf.att.com
+** Expect 201 **
+Admin testid@aaf.att.com added to com.test.TC_Realm1.@[THE_USER].project1
+
+# TC_Realm1.20.5.POS Delete - default domain appended
+ns admin del com.test.TC_Realm1.@[user.name].project1 @[user.name]
+** Expect 200 **
+Admin @[THE_USER]@csp.att.com deleted from com.test.TC_Realm1.@[THE_USER].project1
+
+# TC_Realm1.20.6.POS Add admin - default domain appended
+ns admin add com.test.TC_Realm1.@[user.name].project1 @[user.name]
+** Expect 201 **
+Admin @[THE_USER]@csp.att.com added to com.test.TC_Realm1.@[THE_USER].project1
+
+# TC_Realm1.30.1.POS Create role to add to users
+role create com.test.TC_Realm1.@[user.name].role1
+** Expect 201 **
+Created Role
+
+# TC_Realm1.30.2.NEG Add user, but default domain wrong
+role user add com.test.TC_Realm1.@[user.name].role1 testunused
+** Expect 403 **
+Failed [SVC1403]: Forbidden - AT&T reports that testunused@csp.att.com is a faulty ID
+
+# TC_Realm1.30.3.POS Add user, with default domain appended
+role user add com.test.TC_Realm1.@[user.name].role1 @[user.name]
+** Expect 201 **
+Added User [@[THE_USER]@csp.att.com] to Role [com.test.TC_Realm1.@[THE_USER].role1]
+
+# TC_Realm1.30.10.POS Role list, with default domain added
+role list user testunused
+** Expect 200 **
+
+List Roles for User [testunused@csp.att.com]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+
+# TC_Realm1.30.80.POS Delete user, with default domain appended
+role user del com.test.TC_Realm1.@[user.name].role1 @[user.name]
+** Expect 200 **
+Removed User [@[THE_USER]@csp.att.com] from Role [com.test.TC_Realm1.@[THE_USER].role1]
+
+# TC_Realm1.40.1.POS Create role to add to users
+role create com.test.TC_Realm1.@[user.name].role2
+** Expect 201 **
+Created Role
+
+# TC_Realm1.40.2.NEG Add user, but default domain wrong
+user role add testunused com.test.TC_Realm1.@[user.name].role2
+** Expect 403 **
+Failed [SVC1403]: Forbidden - AT&T reports that testunused@csp.att.com is a faulty ID
+
+# TC_Realm1.40.3.POS Add user, with default domain appended
+user role add @[user.name] com.test.TC_Realm1.@[user.name].role2 
+** Expect 201 **
+Added Role [com.test.TC_Realm1.@[THE_USER].role2] to User [@[THE_USER]@csp.att.com]
+
+# TC_Realm1.40.10.NEG Add delegate, but default domain wrong
+user delegate add testunused testid 2099-01-01
+** Expect 404 **
+Failed [SVC5404]: Not Found - [testunused@csp.att.com] is not a user in the company database.
+
+# TC_Realm1.40.11.POS Add delegate, with default domain appended
+force user delegate add @[user.name] @[user.name] 2099-01-01
+** Expect 201 **
+Delegate Added
+
+# TC_Realm1.40.12.POS Update delegate, with default domain appended
+user delegate upd @[user.name] @[user.name] 2099-01-01
+** Expect 200 **
+Delegate Updated
+
+as XX@NS
+# TC_Realm1.40.20.POS List delegate, with default domain appended
+user list delegates user @[user.name]
+** Expect 200 **
+
+List Delegates by user[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+# TC_Realm1.40.21.POS List delegate, with default domain appended
+user list delegates delegate @[user.name]
+** Expect 200 **
+
+List Delegates by delegate[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+as testid@aaf.att.com
+# TC_Realm1.40.80.POS Delete user, with default domain appended
+user role del @[user.name] com.test.TC_Realm1.@[user.name].role2 
+** Expect 200 **
+Removed Role [com.test.TC_Realm1.@[THE_USER].role2] from User [@[THE_USER]@csp.att.com]
+
+# TC_Realm1.40.81.POS Delete delegate, with default domain appended
+user delegate del @[user.name] 
+** Expect 200 **
+Delegate Deleted
+
+as testid@aaf.att.com
+# TC_Realm1.99.1.POS Delete delgates
+user delegate del @[user.name]
+** Expect 200,404 **
+Failed [SVC7404]: Not Found - Cannot delete non-existent Delegate
+
+# TC_Realm1.99.2.POS Delete user roles
+role user del com.test.TC_Realm1.@[user.name].role1 @[user.name]
+** Expect 200,404 **
+Failed [SVC6404]: Not Found - User [ @[THE_USER]@csp.att.com ] is not Assigned to the Role [ com.test.TC_Realm1.@[THE_USER].role1 ]
+
+user role del @[user.name] com.test.TC_Realm1.@[user.name].role2 
+** Expect 200,404 **
+Failed [SVC6404]: Not Found - User [ @[THE_USER]@csp.att.com ] is not Assigned to the Role [ com.test.TC_Realm1.@[THE_USER].role2 ]
+
+# TC_Realm1.99.3.POS Delete roles
+role delete com.test.TC_Realm1.@[user.name].role1
+** Expect 200,404 **
+Deleted Role
+
+role delete com.test.TC_Realm1.@[user.name].role2
+** Expect 200,404 **
+Deleted Role
+
+as XX@NS
+# TC_Realm1.99.10.POS UnGrant ability to change delegates
+perm ungrant com.att.aaf.delg com.att change com.test.TC_Realm1.@[user.name].change_delg
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.att.aaf.delg|com.att|change] not associated with any Role
+
+as testid@aaf.att.com
+# TC_Realm1.99.11.POS Delete role to change delegates
+set force true
+set force=true role delete com.test.TC_Realm1.@[user.name].change_delg
+** Expect 200,404 **
+Deleted Role
+
+# TC_Realm1.99.98.POS Delete Namespaces
+ns delete com.test.TC_Realm1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+ns delete com.test.TC_Realm1.@[user.name].project1
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Realm1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_Realm1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Realm1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Role1.expected b/authz-test/TestSuite/expected/TC_Role1.expected
new file mode 100644
index 0000000..5cb610f
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Role1.expected
@@ -0,0 +1,369 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Role1.10.0.POS Validate NS ok
+ns list name com.test.TC_Role1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Role1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_Role1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Role1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_Role1.@[user.name].cred_admin
+** Expect 201 **
+Created Role
+
+as XX@NS
+# TC_Role1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_Role1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_Role1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_Role1.10.12.POS Assign user for creating creds
+user role add testid@aaf.att.com com.test.TC_Role1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_Role1.@[THE_USER].cred_admin] to User [testid@aaf.att.com]
+
+# TC_Role1.20.1.POS List Data on non-Empty NS
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].admin                                          
+        com.test.TC_Role1.@[THE_USER].cred_admin                                     
+        com.test.TC_Role1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Role1.@[THE_USER].access *                        *              
+        com.test.TC_Role1.@[THE_USER].access *                        read           
+
+# TC_Role1.20.2.POS Add Roles 
+role create com.test.TC_Role1.@[user.name].r.A
+** Expect 201 **
+Created Role
+
+role create com.test.TC_Role1.@[user.name].r.B
+** Expect 201 **
+Created Role
+
+# TC_Role1.20.3.POS List Data on non-Empty NS
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].admin                                          
+        com.test.TC_Role1.@[THE_USER].cred_admin                                     
+        com.test.TC_Role1.@[THE_USER].owner                                          
+        com.test.TC_Role1.@[THE_USER].r.A                                            
+        com.test.TC_Role1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Role1.@[THE_USER].access *                        *              
+        com.test.TC_Role1.@[THE_USER].access *                        read           
+
+# TC_Role1.20.4.NEG Don't write over Role
+role create com.test.TC_Role1.@[user.name].r.A
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - Role [com.test.TC_Role1.@[THE_USER].r.A] already exists
+
+# TC_Role1.20.5.NEG Don't allow non-user to create
+as bogus
+role create com.test.TC_Role1.@[user.name].r.No
+** Expect 401 **
+Failed with code 401, Unauthorized
+
+# TC_Role1.20.6.NEG Don't allow non-user to create without Approval
+as testunused@aaf.att.com
+role create com.test.TC_Role1.@[user.name].r.No
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not write Role [com.test.TC_Role1.@[THE_USER].r.No]
+
+# TC_Role1.20.10.NEG Non-admins can't change description
+as testunused@aaf.att.com
+role describe com.test.TC_Role1.@[user.name].r.A Description A
+** Expect 403 **
+Failed [SVC1403]: Forbidden - You do not have approval to change com.test.TC_Role1.@[THE_USER].r.A
+
+# TC_Role1.20.11.NEG Role must exist to change description
+as testid@aaf.att.com
+role describe com.test.TC_Role1.@[user.name].r.C Description C
+** Expect 404 **
+Failed [SVC1404]: Not Found - Role [com.test.TC_Role1.@[THE_USER].r.C] does not exist
+
+# TC_Role1.20.12.POS Admin can change description
+role describe com.test.TC_Role1.@[user.name].r.A Description A
+** Expect 200 **
+Description added to role
+
+# TC_Role1.30.1.POS List Data on non-Empty NS
+as testid@aaf.att.com
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].admin                                          
+        com.test.TC_Role1.@[THE_USER].cred_admin                                     
+        com.test.TC_Role1.@[THE_USER].owner                                          
+        com.test.TC_Role1.@[THE_USER].r.A                                            
+        com.test.TC_Role1.@[THE_USER].r.B                                            
+    Permissions
+        com.test.TC_Role1.@[THE_USER].access *                        *              
+        com.test.TC_Role1.@[THE_USER].access *                        read           
+
+# TC_Role1.30.2.POS Create Sub-ns when Roles that exist
+ns create com.test.TC_Role1.@[user.name].r @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Role1.30.3.POS List Data on NS with sub-roles
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].admin                                          
+        com.test.TC_Role1.@[THE_USER].cred_admin                                     
+        com.test.TC_Role1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Role1.@[THE_USER].access *                        *              
+        com.test.TC_Role1.@[THE_USER].access *                        read           
+
+ns list name com.test.TC_Role1.@[user.name].r
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER].r]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER].r
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].r.A                                            
+        com.test.TC_Role1.@[THE_USER].r.B                                            
+        com.test.TC_Role1.@[THE_USER].r.admin                                        
+        com.test.TC_Role1.@[THE_USER].r.owner                                        
+    Permissions
+        com.test.TC_Role1.@[THE_USER].r.access *                        *              
+        com.test.TC_Role1.@[THE_USER].r.access *                        read           
+
+# TC_Role1.40.01.POS List Data on non-Empty NS
+role list role com.test.TC_Role1.@[user.name].r.A
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role1.@[THE_USER].r.A]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER].r.A                      
+
+# TC_Role1.40.20.POS Create a Perm, and add to Role
+perm create com.test.TC_Role1.@[user.name].samplePerm1 some.long(involved).text SELECT com.test.TC_Role1.@[user.name].r.A
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role1.@[THE_USER].samplePerm1|some.long(involved).text|SELECT] to Role [com.test.TC_Role1.@[THE_USER].r.A]
+
+# TC_Role1.40.25.POS List
+role list role com.test.TC_Role1.@[user.name].r.A
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role1.@[THE_USER].r.A]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER].r.A                      
+   com.test.TC_Role1.@[THE_USER].samplePerm1 some.long(involved).text       SELECT         
+
+# TC_Role1.40.30.POS Create a Perm 
+perm create com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case 
+** Expect 201 **
+Created Permission
+
+# TC_Role1.40.32.POS Separately Grant Perm
+perm grant com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case com.test.TC_Role1.@[user.name].r.A
+** Expect 201 **
+Granted Permission [com.test.TC_Role1.@[THE_USER].samplePerm1|some.other_long(less.involved).text|lower_case] to Role [com.test.TC_Role1.@[THE_USER].r.A]
+
+# TC_Role1.40.35.POS List
+role list role com.test.TC_Role1.@[user.name].r.A
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role1.@[THE_USER].r.A]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER].r.A                      
+   com.test.TC_Role1.@[THE_USER].samplePerm1 some.long(involved).text       SELECT         
+   com.test.TC_Role1.@[THE_USER].samplePerm1 some.other_long(less.involved).text lower_case     
+
+# TC_Role1.50.1.POS Create user to attach to role
+user cred add m00001@@[user.name].TC_Role1.test.com password123
+** Expect 201 **
+Added Credential [m00001@@[THE_USER].TC_Role1.test.com]
+
+# TC_Role1.50.2.POS Create new role
+role create com.test.TC_Role1.@[user.name].r.C
+** Expect 201 **
+Created Role
+
+# TC_Role1.50.3.POS Attach user to role
+user role add m00001@@[user.name].TC_Role1.test.com com.test.TC_Role1.@[user.name].r.C
+** Expect 201 **
+Added Role [com.test.TC_Role1.@[THE_USER].r.C] to User [m00001@@[THE_USER].TC_Role1.test.com]
+
+# TC_Role1.50.4.POS Create permission and attach to role
+perm create com.test.TC_Role1.@[user.name].p.C myInstance myAction com.test.TC_Role1.@[user.name].r.C
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role1.@[THE_USER].p.C|myInstance|myAction] to Role [com.test.TC_Role1.@[THE_USER].r.C]
+
+# TC_Role1.50.20.NEG Delete role with permission and user attached should fail
+role delete com.test.TC_Role1.@[user.name].r.C
+** Expect 424 **
+Failed [SVC1424]: Failed Dependency - Role [com.test.TC_Role1.@[THE_USER].r.C] cannot be deleted as it is used by 1 or more Users.
+
+# TC_Role1.50.21.POS Force delete role should work
+set force true
+set force=true role delete com.test.TC_Role1.@[user.name].r.C
+** Expect 200 **
+Deleted Role
+
+# TC_Role1.50.30.POS List Data on non-Empty NS
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role1.@[THE_USER].admin                                          
+        com.test.TC_Role1.@[THE_USER].cred_admin                                     
+        com.test.TC_Role1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Role1.@[THE_USER].access *                        *              
+        com.test.TC_Role1.@[THE_USER].access *                        read           
+        com.test.TC_Role1.@[THE_USER].p.C   myInstance               myAction       
+        com.test.TC_Role1.@[THE_USER].samplePerm1 some.long(involved).text SELECT         
+        com.test.TC_Role1.@[THE_USER].samplePerm1 some.other_long(less.involved).text lower_case     
+    Credentials
+        m00001@@[THE_USER].TC_Role1.test.com                                         
+
+# Need to let DB catch up on deletes
+sleep 0
+as testid@aaf.att.com
+# TC_Role1.99.05.POS Remove Permissions from "40_reports"
+set force true
+set force=true perm delete com.test.TC_Role1.@[user.name].samplePerm1 some.long(involved).text SELECT
+** Expect 200,404 **
+Deleted Permission
+
+set force true
+set force=true perm delete com.test.TC_Role1.@[user.name].samplePerm1 some.other_long(less.involved).text lower_case
+** Expect 200,404 **
+Deleted Permission
+
+# TC_Role1.99.10.POS Namespace Admin can delete Namepace defined Roles
+force role delete com.test.TC_Role1.@[user.name].r.A
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Role1.@[user.name].r.B
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Role1.@[user.name].r.C
+** Expect 200,404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_Role1.@[THE_USER].r.C] does not exist
+
+# TC_Role1.99.15.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_Role1.@[user.name].cred_admin
+** Expect 200,404 **
+Removed Role [com.test.TC_Role1.@[THE_USER].cred_admin] from User [testid@aaf.att.com]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_Role1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_Role1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+role delete com.test.TC_Role1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_Role1.99.20.POS Namespace Admin can delete permissions and credentials
+perm delete com.test.TC_Role1.@[user.name].p.C myInstance myAction
+** Expect 200,404 **
+Deleted Permission
+
+set force true
+user cred del m00001@@[user.name].TC_Role1.test.com
+** Expect 200,404 **
+Deleted Credential [m00001@@[THE_USER].TC_Role1.test.com]
+
+# TC_Role1.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Role1.@[user.name].r
+** Expect 200,404 **
+Deleted Namespace
+
+force ns delete com.test.TC_Role1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Role1.99.99.POS List to prove clean Namespaces
+ns list name com.test.TC_Role1.@[user.name].r
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER].r]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Role1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Role1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Role2.expected b/authz-test/TestSuite/expected/TC_Role2.expected
new file mode 100644
index 0000000..45abf9f
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Role2.expected
@@ -0,0 +1,447 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_Role2.10.0.POS Print NS to prove ok
+ns list name com.test.TC_Role2.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Role2.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_Role2.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+##############
+# Testing Model
+# We are making a Testing model based loosely on George Orwell's Animal Farm
+# In Animal Farm, Animals did all the work but didn't get any priviledges.
+#   In our test, the animals can't see anything but their own role, etc
+# Dogs were supervisors, and ostensibly did something, though mostly laid around
+#   In our test, they have Implicit Permissions by being Admins
+# Pigs were the Elite.  They did nothing, but watch everyone and eat the produce
+#   In our test, they have Explicit Permissions to see everything they want
+##############
+as testid@aaf.att.com
+# TC_Role2.20.1.POS List Data on non-Empty NS
+ns list name com.test.TC_Role2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role2.@[THE_USER].admin                                          
+        com.test.TC_Role2.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_Role2.@[THE_USER].access *                        *              
+        com.test.TC_Role2.@[THE_USER].access *                        read           
+
+# TC_Role2.20.10.POS Create Orwellian Roles
+role create com.test.TC_Role2.@[user.name].r.animals 
+** Expect 201 **
+Created Role
+
+role create com.test.TC_Role2.@[user.name].r.dogs
+** Expect 201 **
+Created Role
+
+role create com.test.TC_Role2.@[user.name].r.pigs 
+** Expect 201 **
+Created Role
+
+# TC_Role2.20.20.POS Create and Grant Perms to Dog Roles
+perm create com.test.TC_Role2.@[user.name].r.A garbage eat com.test.TC_Role2.@[user.name].r.animals
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role2.@[THE_USER].r.A|garbage|eat] to Role [com.test.TC_Role2.@[THE_USER].r.animals]
+
+perm create com.test.TC_Role2.@[user.name].r.A grain eat com.test.TC_Role2.@[user.name].r.dogs
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role2.@[THE_USER].r.A|grain|eat] to Role [com.test.TC_Role2.@[THE_USER].r.dogs]
+
+perm create com.test.TC_Role2.@[user.name].r.A grain * com.test.TC_Role2.@[user.name].r.dogs
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role2.@[THE_USER].r.A|grain|*] to Role [com.test.TC_Role2.@[THE_USER].r.dogs]
+
+perm create com.test.TC_Role2.@[user.name].r.A * * com.test.TC_Role2.@[user.name].r.dogs
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_Role2.@[THE_USER].r.A|*|*] to Role [com.test.TC_Role2.@[THE_USER].r.dogs]
+
+# TC_Role2.20.25.POS Create and Grant Animal Farm Priviledges to Pigs
+as XX@NS
+perm create com.att.aaf.role com.test.TC_Role2.@[user.name].r.animals view com.test.TC_Role2.@[user.name].r.pigs
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.role|com.test.TC_Role2.@[THE_USER].r.animals|view] to Role [com.test.TC_Role2.@[THE_USER].r.pigs]
+
+perm create com.att.aaf.role com.test.TC_Role2.@[user.name].r.dogs view com.test.TC_Role2.@[user.name].r.pigs
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.role|com.test.TC_Role2.@[THE_USER].r.dogs|view] to Role [com.test.TC_Role2.@[THE_USER].r.pigs]
+
+# TC_Role2.20.60.POS List Data on non-Empty NS
+as testid@aaf.att.com
+ns list name com.test.TC_Role2.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Role2.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Role2.@[THE_USER].admin                                          
+        com.test.TC_Role2.@[THE_USER].owner                                          
+        com.test.TC_Role2.@[THE_USER].r.animals                                      
+        com.test.TC_Role2.@[THE_USER].r.dogs                                         
+        com.test.TC_Role2.@[THE_USER].r.pigs                                         
+    Permissions
+        com.test.TC_Role2.@[THE_USER].access *                        *              
+        com.test.TC_Role2.@[THE_USER].access *                        read           
+        com.test.TC_Role2.@[THE_USER].r.A   *                        *              
+        com.test.TC_Role2.@[THE_USER].r.A   garbage                  eat            
+        com.test.TC_Role2.@[THE_USER].r.A   grain                    *              
+        com.test.TC_Role2.@[THE_USER].r.A   grain                    eat            
+
+as XX@NS
+# TC_Role2.40.1.POS List Data on Role
+role list role com.test.TC_Role2.@[user.name].r.animals
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.animals]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.animals                
+   com.test.TC_Role2.@[THE_USER].r.A   garbage                        eat            
+
+role list role com.test.TC_Role2.@[user.name].r.dogs
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.dogs]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+
+role list role com.test.TC_Role2.@[user.name].r.pigs
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.pigs]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.40.10.POS Add testunused to animals
+as testid@aaf.att.com
+user role add testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.animals
+** Expect 201 **
+Added Role [com.test.TC_Role2.@[THE_USER].r.animals] to User [testunused@aaf.att.com]
+
+# TC_Role2.40.11.POS List by Name when part of role
+as testunused@aaf.att.com
+role list role com.test.TC_Role2.@[user.name].r.animals
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.animals]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.animals                
+   com.test.TC_Role2.@[THE_USER].r.A   garbage                        eat            
+
+# TC_Role2.40.12.NEG List by Name when not part of Role
+role list role com.test.TC_Role2.@[user.name].r.dogs
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Role2.@[THE_USER].r.dogs]
+
+role list role com.test.TC_Role2.@[user.name].r.pigs
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Role2.@[THE_USER].r.pigs]
+
+# TC_Role2.40.30.POS Read various Roles based on being Admin in Namespace
+as testid@aaf.att.com
+role list role com.test.TC_Role2.@[user.name].r.animals
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.animals]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.animals                
+   com.test.TC_Role2.@[THE_USER].r.A   garbage                        eat            
+
+role list role com.test.TC_Role2.@[user.name].r.dogs
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.dogs]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+
+role list role com.test.TC_Role2.@[user.name].r.pigs
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.pigs]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.40.50.POS Change testunused to Pigs
+as testid@aaf.att.com
+user role del testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.animals
+** Expect 200 **
+Removed Role [com.test.TC_Role2.@[THE_USER].r.animals] from User [testunused@aaf.att.com]
+
+user role add testunused@aaf.att.com com.test.TC_Role2.@[user.name].r.pigs
+** Expect 201 **
+Added Role [com.test.TC_Role2.@[THE_USER].r.pigs] to User [testunused@aaf.att.com]
+
+# TC_Role2.40.51.POS Read various Roles based on having Explicit Permissions
+as testunused@aaf.att.com
+role list role com.test.TC_Role2.@[user.name].r.animals
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Role2.@[THE_USER].r.animals]
+
+role list role com.test.TC_Role2.@[user.name].r.dogs
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_Role2.@[THE_USER].r.dogs]
+
+role list role com.test.TC_Role2.@[user.name].r.pigs
+** Expect 200 **
+
+List Roles for Role[com.test.TC_Role2.@[THE_USER].r.pigs]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.41.10.POS List by User when Same as Caller
+as testunused@aaf.att.com
+role list user testunused@aaf.att.com
+** Expect 200 **
+
+List Roles for User [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.41.15.POS List by User when not same as Caller, but own/admin namespace of Roles
+as testid@aaf.att.com
+role list user testunused@aaf.att.com
+** Expect 200 **
+
+List Roles for User [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.41.20.POS List by User when not same as Caller, but parent owner of Namespace
+as XX@NS
+role list user testunused@aaf.att.com
+** Expect 200 **
+
+List Roles for User [testunused@aaf.att.com]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.41.80.NEG List by User when not Caller nor associated to Namespace (nothing should be shown)
+as testunused@aaf.att.com
+role list user XX@NS
+** Expect 200 **
+
+List Roles for User [XX@NS]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+
+# TC_Role2.42.10.POS List Roles from NS when not allowed to see NS
+as testid@aaf.att.com
+role list ns com.test.TC_Role2.@[user.name]
+** Expect 200 **
+
+List Roles by NS [com.test.TC_Role2.@[THE_USER]]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].admin                    
+   com.test.TC_Role2.@[THE_USER].access *                              *              
+com.test.TC_Role2.@[THE_USER].owner                    
+   com.test.TC_Role2.@[THE_USER].access *                              read           
+com.test.TC_Role2.@[THE_USER].r.animals                
+   com.test.TC_Role2.@[THE_USER].r.A   garbage                        eat            
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+com.test.TC_Role2.@[THE_USER].r.pigs                   
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.animals view           
+   com.att.aaf.role               com.test.TC_Role2.@[THE_USER].r.dogs view           
+
+# TC_Role2.42.20.NEG Don't List Roles from NS when not allowed to see NS
+as testunused@aaf.att.com
+role list ns com.test.TC_Role2.@[user.name]
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read in NS [com.test.TC_Role2.@[THE_USER]]
+
+# TC_Role2.43.10.POS List Roles when allowed to see Perm
+as testid@aaf.att.com
+role list perm com.test.TC_Role2.@[user.name].r.A grain eat
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Role2.@[THE_USER].r.A|grain|eat
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+
+role list perm com.test.TC_Role2.@[user.name].r.A grain *
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Role2.@[THE_USER].r.A|grain|*
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+
+role list perm com.test.TC_Role2.@[user.name].r.A * *
+** Expect 200 **
+
+List Roles by Perm com.test.TC_Role2.@[THE_USER].r.A|*|*
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.test.TC_Role2.@[THE_USER].r.dogs                   
+   com.test.TC_Role2.@[THE_USER].r.A   *                              *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          *              
+   com.test.TC_Role2.@[THE_USER].r.A   grain                          eat            
+
+# TC_Role2.43.15.NEG Don't List Roles when not allowed to see Perm
+as testunused@aaf.att.com
+role list perm com.test.TC_Role2.@[user.name].r.A grain eat
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Perm [com.test.TC_Role2.@[THE_USER].r.A|grain|eat]
+
+role list perm com.test.TC_Role2.@[user.name].r.A grain *
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Perm [com.test.TC_Role2.@[THE_USER].r.A|grain|*]
+
+role list perm com.test.TC_Role2.@[user.name].r.A * *
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Perm [com.test.TC_Role2.@[THE_USER].r.A|*|*]
+
+as XX@NS
+# TC_Role2.99.1.POS Delete Roles
+force role delete com.test.TC_Role2.@[user.name].r.animals
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Role2.@[user.name].r.dogs
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_Role2.@[user.name].r.pigs
+** Expect 200,404 **
+Deleted Role
+
+# TC_Role2.99.2.POS Delete Perms
+force perm delete com.test.TC_Role2.@[user.name].r.A garbage eat
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Role2.@[user.name].r.A grain eat
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Role2.@[user.name].r.A grain *
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_Role2.@[user.name].r.A * *
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.att.aaf.role com.test.TC_Role2.@[user.name].r.animals view
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.att.aaf.role com.test.TC_Role2.@[user.name].r.dogs view
+** Expect 200,404 **
+Deleted Permission
+
+# TC_Role2.99.2.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_Role2.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Role2.99.3.POS Print Namespaces
+ns list name com.test.TC_Role2.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Role2.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_UR1.expected b/authz-test/TestSuite/expected/TC_UR1.expected
new file mode 100644
index 0000000..7630488
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_UR1.expected
@@ -0,0 +1,266 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_UR1.10.0.POS Validate no NS
+ns list name com.test.TC_UR1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_UR1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_UR1.10.1.POS Create Namespace to add IDs
+ns create com.test.TC_UR1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Role1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_UR1.@[user.name].cred_admin
+** Expect 201 **
+Created Role
+
+as XX@NS
+# TC_Role1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_UR1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_UR1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_Role1.10.12.POS Assign user for creating creds
+user role add testid@aaf.att.com com.test.TC_UR1.@[user.name].cred_admin
+** Expect 201 **
+Added Role [com.test.TC_UR1.@[THE_USER].cred_admin] to User [testid@aaf.att.com]
+
+# TC_UR1.10.20.POS Create two Credentials
+user cred add m00001@@[user.name].TC_UR1.test.com "abc123sd"
+** Expect 201 **
+Added Credential [m00001@@[THE_USER].TC_UR1.test.com]
+
+user cred add m00002@@[user.name].TC_UR1.test.com "abc123sd"
+** Expect 201 **
+Added Credential [m00002@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.10.21.POS Create two Roles
+role create com.test.TC_UR1.@[user.name].r1
+** Expect 201 **
+Created Role
+
+role create com.test.TC_UR1.@[user.name].r2
+** Expect 201 **
+Created Role
+
+# TC_UR1.23.1.NEG Too Few Args for User Role 1
+user 
+** Expect 0 **
+user role <add|del|setTo|extend> <user> [role[,role]* (!REQ S)] 
+     cred <add|del|reset|extend> <id> [password (! D|E)] [entry# (if multi)] 
+     delegate <add|upd|del> <from> [to REQ A&U] [until (YYYY-MM-DD) REQ A] 
+     list role <role> 
+          perm <type> <instance> <action> 
+          cred <ns|id> <value> 
+          delegates <user|delegate> <id> 
+          approvals <user|approver|ticket> <value> 
+          activity <user> 
+
+# TC_UR1.23.2.NEG Too Few Args for user role
+user role
+** Expect -1 **
+Too few args: role <add|del|setTo|extend> <user> [role[,role]* (!REQ S)] 
+
+# TC_UR1.23.3.NEG Too Few Args for user role add
+user role add
+** Expect -1 **
+Too few args: role <add|del|setTo|extend> <user> [role[,role]* (!REQ S)] 
+
+# TC_UR1.30.10.POS Create a UserRole
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+** Expect 201 **
+Added Role [com.test.TC_UR1.@[THE_USER].r1] to User [m00001@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.30.11.NEG Created UserRole Exists
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+
+# TC_UR1.30.13.POS Delete UserRole 
+sleep 0
+user role del m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+** Expect 200 **
+Removed Role [com.test.TC_UR1.@[THE_USER].r1] from User [m00001@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.30.20.POS Create multiple UserRoles
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+** Expect 201 **
+Added Role [com.test.TC_UR1.@[THE_USER].r1] to User [m00001@@[THE_USER].TC_UR1.test.com]
+Added Role [com.test.TC_UR1.@[THE_USER].r2] to User [m00001@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.30.21.NEG Created UserRole Exists
+user role add m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+
+# TC_UR1.30.23.POS Delete UserRole 
+sleep 0
+user role del m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+** Expect 200 **
+Removed Role [com.test.TC_UR1.@[THE_USER].r1] from User [m00001@@[THE_USER].TC_UR1.test.com]
+Removed Role [com.test.TC_UR1.@[THE_USER].r2] from User [m00001@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.30.30.POS Create a Role User
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com 
+** Expect 201 **
+Added User [m00001@@[THE_USER].TC_UR1.test.com] to Role [com.test.TC_UR1.@[THE_USER].r1]
+
+# TC_UR1.30.31.NEG Created Role User Exists
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com 
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+
+# TC_UR1.30.33.POS Delete Role User
+sleep 0
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com
+** Expect 200 **
+Removed User [m00001@@[THE_USER].TC_UR1.test.com] from Role [com.test.TC_UR1.@[THE_USER].r1]
+
+# TC_UR1.30.40.POS Create multiple Role Users
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+** Expect 201 **
+Added User [m00001@@[THE_USER].TC_UR1.test.com] to Role [com.test.TC_UR1.@[THE_USER].r1]
+Added User [m00002@@[THE_USER].TC_UR1.test.com] to Role [com.test.TC_UR1.@[THE_USER].r1]
+
+# TC_UR1.30.41.NEG Created Role User Exists
+role user add com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+** Expect 409 **
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+Failed [SVC1409]: Conflict Already Exists - User Role exists
+
+# TC_UR1.30.43.POS Delete Role Users 
+sleep 0
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com
+** Expect 200 **
+Removed User [m00001@@[THE_USER].TC_UR1.test.com] from Role [com.test.TC_UR1.@[THE_USER].r1]
+Removed User [m00002@@[THE_USER].TC_UR1.test.com] from Role [com.test.TC_UR1.@[THE_USER].r1]
+
+# TC_UR1.40.10.POS Create multiple UserRoles
+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1,com.test.TC_UR1.@[user.name].r2
+** Expect 200 **
+Set User's Roles to [com.test.TC_UR1.@[THE_USER].r1,com.test.TC_UR1.@[THE_USER].r2]
+
+# TC_UR1.40.11.POS Reset userrole for a user
+user role setTo m00001@@[user.name].TC_UR1.test.com
+** Expect 200 **
+Set User's Roles to []
+
+# TC_UR1.40.12.NEG Create userrole where Role doesn't exist
+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r5
+** Expect 404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_UR1.@[THE_USER].r5] does not exist
+
+# TC_UR1.40.13.NEG Create userrole where User doesn't exist
+user role setTo m99999@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+** Expect 403 **
+Failed [SVC2403]: Forbidden - m99999@@[THE_USER].TC_UR1.test.com is not a valid AAF Credential
+
+as testunused@aaf.att.com
+# TC_UR1.40.19.NEG User without permission tries to add userrole
+user role setTo m00001@@[user.name].TC_UR1.test.com com.test.TC_UR1.@[user.name].r1
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not write Role [com.test.TC_UR1.@[THE_USER].r1]
+
+# TC_UR1.40.20.NEG User without permission tries to add userrole
+role user setTo com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not write Role [com.test.TC_UR1.@[THE_USER].r1]
+
+as testid@aaf.att.com
+# TC_UR1.40.22.POS Reset userrole for a user
+role user setTo com.test.TC_UR1.@[user.name].r1
+** Expect 200 **
+Set the Role to Users []
+
+sleep 0
+# TC_UR1.40.23.NEG Create UserRole where Role doesn't exist
+role user setTo com.test.TC_UR1.@[user.name].r5 m00001@@[user.name].TC_UR1.test.com
+** Expect 404 **
+Failed [SVC3404]: Not Found - Role [com.test.TC_UR1.@[THE_USER].r5] does not exist
+
+sleep 0
+# TC_UR1.40.24.NEG Create UserRole where User doesn't exist
+role user setTo com.test.TC_UR1.@[user.name].r1 m99999@@[user.name].TC_UR1.test.com
+** Expect 403 **
+Failed [SVC2403]: Forbidden - m99999@@[THE_USER].TC_UR1.test.com is not a valid AAF Credential
+
+# Need to let DB catch up on deletes
+sleep 0
+as testid@aaf.att.com
+# TC_UR1.99.1.POS Remove User from Role
+role user del com.test.TC_UR1.@[user.name].r1 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com 
+** Expect 200,404 **
+Failed [SVC6404]: Not Found - User [ m00001@@[THE_USER].TC_UR1.test.com ] is not Assigned to the Role [ com.test.TC_UR1.@[THE_USER].r1 ]
+Failed [SVC6404]: Not Found - User [ m00002@@[THE_USER].TC_UR1.test.com ] is not Assigned to the Role [ com.test.TC_UR1.@[THE_USER].r1 ]
+
+role user del com.test.TC_UR1.@[user.name].r2 m00001@@[user.name].TC_UR1.test.com,m00002@@[user.name].TC_UR1.test.com 
+** Expect 200,404 **
+Failed [SVC6404]: Not Found - User [ m00001@@[THE_USER].TC_UR1.test.com ] is not Assigned to the Role [ com.test.TC_UR1.@[THE_USER].r2 ]
+Failed [SVC6404]: Not Found - User [ m00002@@[THE_USER].TC_UR1.test.com ] is not Assigned to the Role [ com.test.TC_UR1.@[THE_USER].r2 ]
+
+role user setTo com.test.TC_UR1.@[user.name].r1
+** Expect 200,404 **
+Set the Role to Users []
+
+# TC_UR1.99.2.POS Remove ability to create creds
+user role del testid@aaf.att.com com.test.TC_UR1.@[user.name].cred_admin
+** Expect 200,404 **
+Removed Role [com.test.TC_UR1.@[THE_USER].cred_admin] from User [testid@aaf.att.com]
+
+as XX@NS
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_UR1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_UR1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+role delete com.test.TC_UR1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_UR1.99.3.POS Delete Creds
+set force true
+user cred del m00001@@[user.name].TC_UR1.test.com
+** Expect 200,404 **
+Deleted Credential [m00001@@[THE_USER].TC_UR1.test.com]
+
+set force true
+user cred del m00002@@[user.name].TC_UR1.test.com
+** Expect 200,404 **
+Deleted Credential [m00002@@[THE_USER].TC_UR1.test.com]
+
+# TC_UR1.99.4.POS Delete Roles
+set force true
+set force=true role delete com.test.TC_UR1.@[user.name].r1
+** Expect 200,404 **
+Deleted Role
+
+set force true
+set force=true role delete com.test.TC_UR1.@[user.name].r2
+** Expect 200,404 **
+Deleted Role
+
+# TC_UR1.99.5.POS Delete Namespace 
+set force true
+set force=true ns delete com.test.TC_UR1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_UR1.99.99.POS Verify Cleaned NS
+ns list name com.test.TC_UR1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_UR1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_User1.expected b/authz-test/TestSuite/expected/TC_User1.expected
new file mode 100644
index 0000000..e1d304f
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_User1.expected
@@ -0,0 +1,485 @@
+set XX@NS <pass>
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set bogus@aaf.att.com boguspass
+set m99990@@[THE_USER].TC_User1.test.com password123
+set m99995@@[THE_USER].TC_User1.test.com password123
+#delay 10
+set NFR 0
+as testid@aaf.att.com
+# TC_User1.10.0.POS Check for Existing Data
+ns list name com.test.TC_User1.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_User1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_User1.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.test.TC_User1.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_User1.10.10.POS Create role to assign mechid perm to
+role create com.test.TC_User1.@[user.name].cred_admin testid@aaf.att.com
+** Expect 201 **
+Created Role
+Added User [testid@aaf.att.com] to Role [com.test.TC_User1.@[THE_USER].cred_admin]
+
+as XX@NS
+# TC_User1.10.11.POS Assign role to mechid perm
+perm grant com.att.aaf.mechid com.att create com.test.TC_User1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.mechid|com.att|create] to Role [com.test.TC_User1.@[THE_USER].cred_admin]
+
+perm grant com.att.aaf.delg com.att change com.test.TC_User1.@[user.name].cred_admin
+** Expect 201 **
+Granted Permission [com.att.aaf.delg|com.att|change] to Role [com.test.TC_User1.@[THE_USER].cred_admin]
+
+as testid@aaf.att.com
+# TC_User1.01.99.POS Expect Namespace to be created
+ns list name com.test.TC_User1.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_User1.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_User1.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_User1.@[THE_USER].admin                                          
+        com.test.TC_User1.@[THE_USER].cred_admin                                     
+        com.test.TC_User1.@[THE_USER].owner                                          
+    Permissions
+        com.test.TC_User1.@[THE_USER].access *                        *              
+        com.test.TC_User1.@[THE_USER].access *                        read           
+
+as testid@aaf.att.com
+# TC_User1.20.1.POS Create roles
+role create com.test.TC_User1.@[user.name].manager
+** Expect 201 **
+Created Role
+
+role create com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Created Role
+
+# TC_User1.20.2.POS Create permissions
+perm create com.test.TC_User1.@[user.name].supplies * move com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_User1.@[THE_USER].supplies|*|move] to Role [com.test.TC_User1.@[THE_USER].worker]
+
+perm create com.test.TC_User1.@[user.name].supplies * stock com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_User1.@[THE_USER].supplies|*|stock] to Role [com.test.TC_User1.@[THE_USER].worker]
+
+perm create com.test.TC_User1.@[user.name].schedule worker create com.test.TC_User1.@[user.name].manager
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_User1.@[THE_USER].schedule|worker|create] to Role [com.test.TC_User1.@[THE_USER].manager]
+
+perm create com.test.TC_User1.@[user.name].worker * annoy com.test.TC_User1.@[user.name].manager
+** Expect 201 **
+Created Permission
+Granted Permission [com.test.TC_User1.@[THE_USER].worker|*|annoy] to Role [com.test.TC_User1.@[THE_USER].manager]
+
+# TC_User1.20.3.POS Create mechid
+user cred add m99990@@[user.name].TC_User1.test.com password123
+** Expect 201 **
+Added Credential [m99990@@[THE_USER].TC_User1.test.com]
+
+user cred add m99995@@[user.name].TC_User1.test.com password123
+** Expect 201 **
+Added Credential [m99995@@[THE_USER].TC_User1.test.com]
+
+as XX@NS
+# TC_User1.20.10.POS Add users to roles
+user role add @[user.name] com.test.TC_User1.@[user.name].manager
+** Expect 201 **
+Added Role [com.test.TC_User1.@[THE_USER].manager] to User [@[THE_USER]@csp.att.com]
+
+user role add m99990@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Added Role [com.test.TC_User1.@[THE_USER].worker] to User [m99990@@[THE_USER].TC_User1.test.com]
+
+# TC_User1.20.20.POS Add Delegate
+as XX@NS
+# TC_User1.20.20.POS Create delegates
+force user delegate add @[user.name] @[user.name]
+** Expect 201 **
+Delegate Added
+
+# TC_User1.40.1.NEG Non-admin, user not in role should not view
+as testunused@aaf.att.com
+user list role com.test.TC_User1.@[user.name].manager
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_User1.@[THE_USER].manager]
+
+user list role com.test.TC_User1.@[user.name].worker
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read Role [com.test.TC_User1.@[THE_USER].worker]
+
+as m99990@@[THE_USER].TC_User1.test.com
+# TC_User1.40.2.NEG Non-admin, user in role should not view
+user list role com.test.TC_User1.@[user.name].manager
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99990@@[THE_USER].TC_User1.test.com] may not read Role [com.test.TC_User1.@[THE_USER].manager]
+
+sleep 0
+# TC_User1.40.3.POS Non-admin, user in role can view himself
+user list role com.test.TC_User1.@[user.name].worker
+** Expect 200 **
+
+List Users for Role[com.test.TC_User1.@[THE_USER].worker]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+as testid@aaf.att.com
+# TC_User1.40.10.POS admin should view
+user list role com.test.TC_User1.@[user.name].manager
+** Expect 200 **
+
+List Users for Role[com.test.TC_User1.@[THE_USER].manager]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+@[THE_USER]@csp.att.com                                 XXXX-XX-XX                    
+
+
+user list role com.test.TC_User1.@[user.name].worker
+** Expect 200 **
+
+List Users for Role[com.test.TC_User1.@[THE_USER].worker]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+as testunused@aaf.att.com
+# TC_User1.41.1.NEG Non-admin, user not in perm should not view
+user list perm com.test.TC_User1.@[user.name].supplies * move
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|move]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|stock]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].schedule|worker|create]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].worker|*|annoy]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+as m99990@@[THE_USER].TC_User1.test.com
+# TC_User1.41.2.POS Non-admin, user in perm can view himself
+user list perm com.test.TC_User1.@[user.name].supplies * move
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|move]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|stock]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+as m99990@@[THE_USER].TC_User1.test.com
+# TC_User1.41.3.NEG Non-admin, user in perm should not view
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].schedule|worker|create]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].worker|*|annoy]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+
+
+as testid@aaf.att.com
+# TC_User1.41.10.POS admin should view
+user list perm com.test.TC_User1.@[user.name].supplies * move
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|move]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|stock]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].schedule worker create
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].schedule|worker|create]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+@[THE_USER]@csp.att.com                                 XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].worker * annoy
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].worker|*|annoy]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+@[THE_USER]@csp.att.com                                 XXXX-XX-XX                    
+
+
+as testunused@aaf.att.com
+# TC_User1.42.1.NEG Unrelated user can't view delegates
+user list delegates user m99990@@[user.name].TC_User1.test.com
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read delegates for [m99990@@[THE_USER].TC_User1.test.com]
+
+user list delegates delegate m99995@@[user.name].TC_User1.test.com
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [testunused@aaf.att.com] may not read delegates for [m99995@@[THE_USER].TC_User1.test.com]
+
+as XX@NS
+# TC_User1.42.10.POS Admin of domain NS can view
+user list delegates user @[user.name]
+** Expect 200 **
+
+List Delegates by user[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+user list delegates delegate @[user.name]
+** Expect 200 **
+
+List Delegates by delegate[@[THE_USER]@csp.att.com]
+--------------------------------------------------------------------------------
+ User                      Delegate                   Expires   
+--------------------------------------------------------------------------------
+ @[THE_USER]@csp.att.com        @[THE_USER]@csp.att.com         XXXX-XX-XX
+
+as testid@aaf.att.com
+# TC_User1.43.1.POS Add another user to worker role
+user role add m99995@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Added Role [com.test.TC_User1.@[THE_USER].worker] to User [m99995@@[THE_USER].TC_User1.test.com]
+
+as m99990@@[THE_USER].TC_User1.test.com
+# TC_User1.43.2.POS User should only see himself here
+user list role com.test.TC_User1.@[user.name].worker
+** Expect 200 **
+
+List Users for Role[com.test.TC_User1.@[THE_USER].worker]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * move
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|move]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|stock]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+as XX@NS
+# TC_User1.43.10.POS Grant explicit user perm to user
+perm create com.att.aaf.user :com.test.TC_User1.@[user.name] view com.test.TC_User1.@[user.name].worker
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.user|:com.test.TC_User1.@[THE_USER]|view] to Role [com.test.TC_User1.@[THE_USER].worker]
+
+as m99990@@[THE_USER].TC_User1.test.com
+# TC_User1.43.11.POS User should see all users of test domain now
+user list role com.test.TC_User1.@[user.name].worker
+** Expect 200 **
+
+List Users for Role[com.test.TC_User1.@[THE_USER].worker]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * move
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|move]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+user list perm com.test.TC_User1.@[user.name].supplies * stock
+** Expect 200 **
+
+List Users for Permission[com.test.TC_User1.@[THE_USER].supplies|*|stock]
+--------------------------------------------------------------------------------
+User                                               Expires                       
+--------------------------------------------------------------------------------
+m99990@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+m99995@@[THE_USER].TC_User1.test.com                    XXXX-XX-XX                    
+
+
+as testid@aaf.att.com
+# TC_User1.99.0.POS Remove user roles 
+user role del @[user.name] com.test.TC_User1.@[user.name].manager
+** Expect 200,404 **
+Removed Role [com.test.TC_User1.@[THE_USER].manager] from User [@[THE_USER]@csp.att.com]
+
+user role del m99990@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+** Expect 200,404 **
+Removed Role [com.test.TC_User1.@[THE_USER].worker] from User [m99990@@[THE_USER].TC_User1.test.com]
+
+user role del m99995@@[user.name].TC_User1.test.com com.test.TC_User1.@[user.name].worker
+** Expect 200,404 **
+Removed Role [com.test.TC_User1.@[THE_USER].worker] from User [m99995@@[THE_USER].TC_User1.test.com]
+
+# TC_User1.99.1.POS Namespace Admin can delete Namepace defined Roles & Perms
+force perm delete com.test.TC_User1.@[user.name].supplies * move 
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_User1.@[user.name].supplies * stock 
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_User1.@[user.name].schedule worker create 
+** Expect 200,404 **
+Deleted Permission
+
+force perm delete com.test.TC_User1.@[user.name].worker * annoy 
+** Expect 200,404 **
+Deleted Permission
+
+force role delete com.test.TC_User1.@[user.name].manager
+** Expect 200,404 **
+Deleted Role
+
+force role delete com.test.TC_User1.@[user.name].worker
+** Expect 200,404 **
+Deleted Role
+
+# TC_User1.99.10.POS Creds and delegate
+user delegate del @[user.name]
+** Expect 200,404 **
+Delegate Deleted
+
+user cred del m99990@@[user.name].TC_User1.test.com
+** Expect 200,404 **
+Deleted Credential [m99990@@[THE_USER].TC_User1.test.com]
+
+user cred del m99995@@[user.name].TC_User1.test.com
+** Expect 200,404 **
+Deleted Credential [m99995@@[THE_USER].TC_User1.test.com]
+
+as XX@NS
+# TC_User1.99.15.POS Remove ability to create creds
+perm ungrant com.att.aaf.mechid com.att create com.test.TC_User1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.mechid|com.att|create] from Role [com.test.TC_User1.@[THE_USER].cred_admin]
+
+perm ungrant com.att.aaf.delg com.att change com.test.TC_User1.@[user.name].cred_admin
+** Expect 200,404 **
+UnGranted Permission [com.att.aaf.delg|com.att|change] from Role [com.test.TC_User1.@[THE_USER].cred_admin]
+
+perm delete com.att.aaf.user :com.test.TC_User1.@[user.name] view
+** Expect 200,404 **
+Deleted Permission
+
+as testid@aaf.att.com
+force role delete com.test.TC_User1.@[user.name].cred_admin
+** Expect 200,404 **
+Deleted Role
+
+# TC_User1.99.90.POS Namespace Admin can delete Namespace
+force ns delete com.test.TC_User1.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+sleep 0
+# TC_User1.99.99.POS Check Clean Namespace
+ns list name com.test.TC_User1.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_User1.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/expected/TC_Wild.expected b/authz-test/TestSuite/expected/TC_Wild.expected
new file mode 100644
index 0000000..448efa1
--- /dev/null
+++ b/authz-test/TestSuite/expected/TC_Wild.expected
@@ -0,0 +1,520 @@
+set testid@aaf.att.com <pass>
+set testunused@aaf.att.com <pass>
+set XX@NS <pass>
+set bogus boguspass
+#delay 10
+set NFR 0
+as XX@NS
+# TC_Wild.10.0.POS Validate NS ok
+ns list name com.att.test.TC_Wild.@[user.name] 
+** Expect 200 **
+
+List Namespaces by Name[com.att.test.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+# TC_Wild.10.1.POS Create Namespace with valid IDs and Responsible Parties
+ns create com.att.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Wild.10.10.POS Create a clean MechID
+user cred add m99999@@[user.name].TC_Wild.att.com aNewPass8
+** Expect 201 **
+Added Credential [m99999@@[THE_USER].TC_Wild.att.com]
+
+set m99999@@[THE_USER].TC_Wild.att.com aNewPass8
+as XX@NS
+# TC_Wild.10.11.POS Create role and assign MechID to
+role create com.att.TC_Wild.@[user.name].service m99999@@[user.name].TC_Wild.att.com
+** Expect 201 **
+Created Role
+Added User [m99999@@[THE_USER].TC_Wild.att.com] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.20.1.NEG Fail to create a perm in NS
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Perm [com.att.TC_Wild.@[THE_USER].myType|myInstance|myAction]
+
+# TC_Wild.20.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+perm create com.att.TC_Wild.@[user.name].access :perm:myType:*:myAction write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.TC_Wild.@[THE_USER].access|:perm:myType:*:myAction|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.20.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  :perm:myType:*:myAction        write     
+
+
+# TC_Wild.20.7.POS Now able to create a perm in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Wild.20.8.POS Print Perms
+as XX@NS
+perm list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Perms by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  *                              *         
+com.att.TC_Wild.@[THE_USER].access  *                              read      
+com.att.TC_Wild.@[THE_USER].access  :perm:myType:*:myAction        write     
+com.att.TC_Wild.@[THE_USER].myType  myInstance                     myAction  
+
+
+# TC_Wild.20.10.POS Delete Perms Created
+force perm delete com.att.TC_Wild.@[user.name].access :perm:myType:*:myAction write
+** Expect 200 **
+Deleted Permission
+
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.21.1.NEG Fail to create a perm in NS
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Perm [com.att.TC_Wild.@[THE_USER].myType|myInstance|myAction]
+
+# TC_Wild.21.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+perm create com.att.TC_Wild.@[user.name].access :perm:myType:*:* write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.TC_Wild.@[THE_USER].access|:perm:myType:*:*|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.21.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  :perm:myType:*:*               write     
+
+
+# TC_Wild.21.7.POS Now able to create a perm in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Wild.21.8.POS Print Perms
+as XX@NS
+perm list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Perms by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  *                              *         
+com.att.TC_Wild.@[THE_USER].access  *                              read      
+com.att.TC_Wild.@[THE_USER].access  :perm:myType:*:*               write     
+com.att.TC_Wild.@[THE_USER].myType  myInstance                     myAction  
+
+
+# TC_Wild.21.10.POS Delete Perms Created
+force perm delete com.att.TC_Wild.@[user.name].access :perm:myType:*:* write
+** Expect 200 **
+Deleted Permission
+
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.30.1.NEG Fail to create a role in NS
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Role [com.att.TC_Wild.@[THE_USER].tool.myRole]
+
+# TC_Wild.30.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+perm create com.att.TC_Wild.@[user.name].access :role:tool.* write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.TC_Wild.@[THE_USER].access|:role:tool.*|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.30.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  :role:tool.*                   write     
+
+
+# TC_Wild.30.7.POS Now able to create a role in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 201 **
+Created Role
+
+# TC_Wild.30.8.POS Print Perms
+as XX@NS
+role list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Roles by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].admin                      
+   com.att.TC_Wild.@[THE_USER].access  *                              *              
+com.att.TC_Wild.@[THE_USER].owner                      
+   com.att.TC_Wild.@[THE_USER].access  *                              read           
+com.att.TC_Wild.@[THE_USER].service                    
+   com.att.TC_Wild.@[THE_USER].access  :role:tool.*                   write          
+com.att.TC_Wild.@[THE_USER].tool.myRole                
+
+# TC_Wild.30.10.POS Delete Perms Created
+force perm delete com.att.TC_Wild.@[user.name].access :role:tool.* write
+** Expect 200 **
+Deleted Permission
+
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 200 **
+Deleted Role
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.31.1.NEG Fail to create a role in NS
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Role [com.att.TC_Wild.@[THE_USER].tool.myRole]
+
+# TC_Wild.31.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+perm create com.att.TC_Wild.@[user.name].access :role:* write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.TC_Wild.@[THE_USER].access|:role:*|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.31.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  :role:*                        write     
+
+
+# TC_Wild.31.7.POS Now able to create a role in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 201 **
+Created Role
+
+# TC_Wild.31.8.POS Print Perms
+as XX@NS
+role list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Roles by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].admin                      
+   com.att.TC_Wild.@[THE_USER].access  *                              *              
+com.att.TC_Wild.@[THE_USER].owner                      
+   com.att.TC_Wild.@[THE_USER].access  *                              read           
+com.att.TC_Wild.@[THE_USER].service                    
+   com.att.TC_Wild.@[THE_USER].access  :role:*                        write          
+com.att.TC_Wild.@[THE_USER].tool.myRole                
+
+# TC_Wild.31.10.POS Delete Perms Created
+force perm delete com.att.TC_Wild.@[user.name].access :role:* write
+** Expect 200 **
+Deleted Permission
+
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 200 **
+Deleted Role
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.32.1.NEG Fail to create a role in NS
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Role [com.att.TC_Wild.@[THE_USER].tool.myRole]
+
+# TC_Wild.32.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+perm create com.att.TC_Wild.@[user.name].access :role:* * com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.TC_Wild.@[THE_USER].access|:role:*|*] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.32.5.POS Print Perms
+as m99999@@[THE_USER].TC_Wild.att.com
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  :role:*                        *         
+
+
+# TC_Wild.32.7.POS Now able to create a role in NS
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 201 **
+Created Role
+
+# TC_Wild.32.8.POS May Print Role
+role list role com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 200 **
+
+List Roles for Role[com.att.TC_Wild.@[THE_USER].tool.myRole]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].tool.myRole                
+
+as XX@NS
+# TC_Wild.32.10.POS Delete Perms Created
+force perm delete com.att.TC_Wild.@[user.name].access :role:* *
+** Expect 200 **
+Deleted Permission
+
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 200 **
+Deleted Role
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.50.1.NEG Fail to create a perm in NS
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Perm [com.att.TC_Wild.@[THE_USER].myType|myInstance|myAction]
+
+# TC_Wild.50.3.POS Add "access perm" based Wild Card with specific Action
+as XX@NS
+perm create com.att.aaf.ns :com.att.*:perm:myType:*:* write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.ns|:com.att.*:perm:myType:*:*|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.50.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.aaf.ns                 :com.att.*:perm:myType:*:*     write     
+
+
+# TC_Wild.50.7.POS Now able to create a perm in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+perm create com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 201 **
+Created Permission
+
+# TC_Wild.50.8.POS Print Perms
+as XX@NS
+perm list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Perms by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].access  *                              *         
+com.att.TC_Wild.@[THE_USER].access  *                              read      
+com.att.TC_Wild.@[THE_USER].myType  myInstance                     myAction  
+
+
+# TC_Wild.50.10.POS Delete Perms Created
+force perm delete com.att.aaf.ns :com.att.*:perm:myType:*:* write 
+** Expect 200 **
+Deleted Permission
+
+force perm delete com.att.TC_Wild.@[user.name].myType myInstance myAction
+** Expect 200 **
+Deleted Permission
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.51.1.NEG Fail to create a role in NS
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write Role [com.att.TC_Wild.@[THE_USER].tool.myRole]
+
+# TC_Wild.51.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+perm create com.att.aaf.ns :com.att.*:role:tool.* write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.ns|:com.att.*:role:tool.*|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.51.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.aaf.ns                 :com.att.*:role:tool.*         write     
+
+
+# TC_Wild.51.7.POS Now able to create a role in NS
+as m99999@@[THE_USER].TC_Wild.att.com
+role create com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 201 **
+Created Role
+
+# TC_Wild.51.8.POS Print Perms
+as XX@NS
+role list ns com.att.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Roles by NS [com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+ROLE Name                                         
+   PERM Type                      Instance                       Action         
+--------------------------------------------------------------------------------
+com.att.TC_Wild.@[THE_USER].admin                      
+   com.att.TC_Wild.@[THE_USER].access  *                              *              
+com.att.TC_Wild.@[THE_USER].owner                      
+   com.att.TC_Wild.@[THE_USER].access  *                              read           
+com.att.TC_Wild.@[THE_USER].service                    
+   com.att.aaf.ns                 :com.att.*:role:tool.*         write          
+com.att.TC_Wild.@[THE_USER].tool.myRole                
+
+# TC_Wild.51.10.POS Delete Perms Created
+force perm delete com.att.aaf.ns :com.att.*:role:tool.* write
+** Expect 200 **
+Deleted Permission
+
+force role delete com.att.TC_Wild.@[user.name].tool.myRole
+** Expect 200 **
+Deleted Role
+
+as m99999@@[THE_USER].TC_Wild.att.com
+# TC_Wild.52.1.NEG Fail to create a NS
+ns create com.test.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 403 **
+Failed [SVC1403]: Forbidden - [m99999@@[THE_USER].TC_Wild.att.com] may not write in NS [com.test]
+
+# TC_Wild.52.3.POS Add "access role" based Wild Card with specific Action
+as XX@NS
+perm create com.att.aaf.ns :com.test:ns write com.att.TC_Wild.@[user.name].service
+** Expect 201 **
+Created Permission
+Granted Permission [com.att.aaf.ns|:com.test:ns|write] to Role [com.att.TC_Wild.@[THE_USER].service]
+
+# TC_Wild.52.5.POS Print Perms
+perm list user m99999@@[user.name].TC_Wild.att.com
+** Expect 200 **
+
+List Permissions by User[m99999@@[THE_USER].TC_Wild.att.com]
+--------------------------------------------------------------------------------
+PERM Type                      Instance                       Action    
+--------------------------------------------------------------------------------
+com.att.aaf.ns                 :com.test:ns                   write     
+
+
+# TC_Wild.52.7.POS Now able to create an NS
+as m99999@@[THE_USER].TC_Wild.att.com
+ns create com.test.TC_Wild.@[user.name] @[user.name] testid@aaf.att.com
+** Expect 201 **
+Created Namespace
+
+# TC_Wild.52.8.POS Print Perms
+as XX@NS
+ns list name com.test.TC_Wild.@[user.name]
+** Expect 200 **
+
+List Namespaces by Name[com.test.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+com.test.TC_Wild.@[THE_USER]
+    Administrators
+        testid@aaf.att.com                                                      
+    Responsible Parties
+        @[THE_USER]@csp.att.com                                                      
+    Roles
+        com.test.TC_Wild.@[THE_USER].admin                                           
+        com.test.TC_Wild.@[THE_USER].owner                                           
+    Permissions
+        com.test.TC_Wild.@[THE_USER].access *                        *              
+        com.test.TC_Wild.@[THE_USER].access *                        read           
+
+# TC_Wild.52.10.POS Delete Perms Created
+force perm delete com.att.aaf.ns :com.test:ns write
+** Expect 200 **
+Deleted Permission
+
+force ns delete com.test.TC_Wild.@[user.name]
+** Expect 200 **
+Deleted Namespace
+
+as XX@NS
+# TC_Wild.99.80.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:perm:*:* write 
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.att.aaf.ns|:com.att.*:perm:*:*|write] does not exist
+
+# TC_Wild.99.81.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:perm:*:* * 
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.att.aaf.ns|:com.att.*:perm:*:*|*] does not exist
+
+# TC_Wild.99.82.POS Cleanup
+force perm delete com.att.aaf.ns :com.att.*:role:* write 
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.att.aaf.ns|:com.att.*:role:*|write] does not exist
+
+# TC_Wild.99.83.POS Cleanup
+force perm delete com.att.aaf.ns :com.test:ns write
+** Expect 200,404 **
+Failed [SVC4404]: Not Found - Permission [com.att.aaf.ns|:com.test:ns|write] does not exist
+
+# TC_Wild.99.90.POS Cleanup
+force ns delete com.test.TC_Wild.@[user.name]
+** Expect 200,404 **
+Failed [SVC2404]: Not Found - com.test.TC_Wild.@[THE_USER] does not exist
+
+# TC_Wild.99.91.POS Cleanup
+force ns delete com.att.TC_Wild.@[user.name]
+** Expect 200,404 **
+Deleted Namespace
+
+# TC_Wild.99.99.POS List to prove clean Namespaces
+ns list name com.att.TC_Wild.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.att.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
+ns list name com.test.TC_Wild.@[user.name]
+** Expect 200,404 **
+
+List Namespaces by Name[com.test.TC_Wild.@[THE_USER]]
+--------------------------------------------------------------------------------
+    *** Namespace Not Found ***
+
diff --git a/authz-test/TestSuite/list b/authz-test/TestSuite/list
new file mode 100644
index 0000000..8742d97
--- /dev/null
+++ b/authz-test/TestSuite/list
@@ -0,0 +1,2 @@
+# /bin/sh
+find . -maxdepth 1 -name "TC*" -exec sh cmds {} \; | grep \#
diff --git a/authz-test/TestSuite/qc b/authz-test/TestSuite/qc
new file mode 100644
index 0000000..83149a3
--- /dev/null
+++ b/authz-test/TestSuite/qc
@@ -0,0 +1,38 @@
+#!/bin/bash
+
+# For Jenkins, we need to keep track of the exit code returned from each tc run;
+# if it's ever non-zero (ie, a failure), must return that value when this script exits
+#
+STATUS=0
+
+for DIR in `ls | grep ^TC_ | sort`; do 
+  echo "**" | tee reports/$DIR.txt
+  echo "** TC Group: $DIR" | tee -a reports/$DIR.txt
+  echo "** Date    : "`date` | tee -a reports/$DIR.txt
+  echo "** By      : "`who | cut -d " " -f 1` | tee -a reports/$DIR.txt
+  echo "**" | tee -a reports/$DIR.txt
+  echo "" >> reports/$DIR.txt
+  echo "-- Description --" >> reports/$DIR.txt
+  cat $DIR/Description  >> reports/$DIR.txt
+  echo -- Positive Cases -- >> reports/$DIR.txt
+  grep -h "^# $DIR.*POS " $DIR/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /  	/' >> reports/$DIR.txt
+  echo >> reports/$DIR.txt
+  echo -- Negative Cases -- >> reports/$DIR.txt
+  grep -h "^# $DIR.*NEG " $DIR/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /	/' >> reports/$DIR.txt
+
+
+  echo "" >> reports/$DIR.txt
+  echo "-- Results" | tee -a reports/$DIR.txt
+  echo "" | tee -a reports/$DIR.txt
+
+  bash ./tc $DIR | tee -a reports/$DIR.txt
+  
+  if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
+      STATUS=1
+  fi
+done
+
+
+exit $STATUS
+
+
diff --git a/authz-test/TestSuite/reset b/authz-test/TestSuite/reset
new file mode 100644
index 0000000..af9b100
--- /dev/null
+++ b/authz-test/TestSuite/reset
@@ -0,0 +1,4 @@
+set m12345=<pass>
+as m12345
+ns create com.test testid@test.com
+
diff --git a/authz-test/TestSuite/rpt1 b/authz-test/TestSuite/rpt1
new file mode 100644
index 0000000..4997ed8
--- /dev/null
+++ b/authz-test/TestSuite/rpt1
@@ -0,0 +1,22 @@
+# /bin/bash
+if [ "$1" == "" ]; then
+  echo "Usage: rpt1 <TestCase>"
+  exit 1
+fi
+
+echo "**"
+echo "** TC Group: $1"
+echo "** Date    : "`date`
+echo "** By      : "`who | cut -d " " -f 1`
+echo "**"
+echo ""
+echo "-- Description --"
+cat $1/Description 
+echo -- Positive Cases --
+grep -h "^# $1.*POS " $1/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /  	/'
+echo
+echo -- Negative Cases --
+grep -h "^# $1.*NEG " $1/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /	/'
+
+cd ..
+exit 0
diff --git a/authz-test/TestSuite/rpt2 b/authz-test/TestSuite/rpt2
new file mode 100644
index 0000000..45eb1e2
--- /dev/null
+++ b/authz-test/TestSuite/rpt2
@@ -0,0 +1,12 @@
+# /bin/bash
+if [ "$1" == "" ]; then
+  echo "Usage: rpt2 <TestCase>"
+  exit 1
+fi
+
+./rpt1 $1
+echo ""
+echo "-- Results"
+echo ""
+./tc $1
+
diff --git a/authz-test/TestSuite/tc b/authz-test/TestSuite/tc
new file mode 100644
index 0000000..ed21c64
--- /dev/null
+++ b/authz-test/TestSuite/tc
Binary files differ
diff --git a/authz-test/etc/tc.connection b/authz-test/etc/tc.connection
new file mode 100644
index 0000000..1fd9f6f
--- /dev/null
+++ b/authz-test/etc/tc.connection
@@ -0,0 +1,32 @@
+# Load Passwords needed
+
+DME2REG=/Volumes/Data/src/authz/dme2reg
+
+# This is a fix for DME2 jar which doesn't register entries correctly
+function fix {
+   for FILE in `find $DME2REG -name "*.txt"`
+   do
+        sed -e"s/null/https/" $FILE > temp3555
+        cat temp3555 > $FILE
+        rm temp3555
+   done
+}
+
+function aafcli {
+  fix
+  java \
+  -Daaf_id=testid \
+  -Daaf_pass=<pass> \
+  -Daaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0.1/envContext=DEV/routeOffer=BAU_SE \
+  -DAFT_LATITUDE=32.780140 \
+  -DAFT_LONGITUDE=-96.800451 \
+  -DAFT_ENVIRONMENT=AFTUAT \
+  -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG \
+  -DDME2_EP_REGISTRY_CLASS=DME2FS \
+  -Dtestid=<pass> \
+  -Dbogus=xxx \
+  -Dm12345=<pass> \
+  -jar \
+   /Volumes/Data/src/authz/authz-cmd/target/authz-cmd-2.0.2-SNAPSHOT-jar-with-dependencies.jar \
+   $*
+}
diff --git a/authz-test/etc/tc.devl b/authz-test/etc/tc.devl
new file mode 100644
index 0000000..a85250c
--- /dev/null
+++ b/authz-test/etc/tc.devl
@@ -0,0 +1,22 @@
+# Load Passwords needed
+if [ -e ../../authz-service ]; then
+   CMD_DEPLOYED=authz-service
+else
+   CMD_DEPLOYED=authz-cmd
+fi
+function aafcli {
+  java \
+  -Daaf_id=testid \
+  -Daaf_pass=<pass> \
+  -Daaf_url=DMEServiceName=service=com.att.authz.AuthorizationService/version=2.0/envContext=AFTUAT/routeOffer=BAU_SE \
+  -Dkeyfile=/Volumes/Data/src/authz/common/keyfile \
+  -DAFT_LATITUDE=38.432930 \
+  -DAFT_LONGITUDE=-90.432480 \
+  -DAFT_ENVIRONMENT=AFTUAT \
+  -Dtestid=<pass> \
+  -Dbogus=xxx \
+  -Dm12345=<pass> \
+  -jar \
+   ../../${CMD_DEPLOYED}/2.0.2/lib/authz-cmd-2.0.2-jar-with-dependencies.jar \
+   $*
+}
diff --git a/authz-test/etc/tc.local b/authz-test/etc/tc.local
new file mode 100644
index 0000000..8aec5c7
--- /dev/null
+++ b/authz-test/etc/tc.local
@@ -0,0 +1,22 @@
+# Load Passwords needed
+
+DME2REG=../../dme2reg
+
+function aafcli {
+  java \
+  -Daaf_id=testid \
+  -Daaf_pass=<pass> \
+  -Daaf_url=https://DME2RESOLVE/service=com.att.authz.AuthorizationService/version=2.0.3/envContext=DEV/routeOffer=BAU_SE \
+  -Dkeyfile=../../common/keyfile \
+  -DAFT_LATITUDE=32.780140 \
+  -DAFT_LONGITUDE=-96.800451 \
+  -DAFT_ENVIRONMENT=AFTUAT \
+  -DAFT_DME2_EP_REGISTRY_FS_DIR=$DME2REG \
+  -DDME2_EP_REGISTRY_CLASS=DME2FS \
+  -Dtestid=<pass> \
+  -Dbogus=xxx \
+  -Dm12345=<pass> \
+  -jar \
+   ../../authz-cmd/target/authz-cmd-2.0.3-jar-with-dependencies.jar \
+   $*
+}
diff --git a/authz-test/pom.xml b/authz-test/pom.xml
new file mode 100644
index 0000000..de32687
--- /dev/null
+++ b/authz-test/pom.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<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>org.onap.aaf.authz</groupId>

+		<artifactId>parent</artifactId>

+		<version>1.0.0-SNAPSHOT</version>

+		<relativePath>../pom.xml</relativePath>

+	</parent>

+		

+	<artifactId>authz-test</artifactId>

+	<name>Authz TestCases</name>

+	<description>TestCase Suite for Authz/Authn</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>0</project.swmVersion>

+					<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>

+        <nexusproxy>https://nexus.onap.org</nexusproxy>

+		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>

+		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>

+		<stagingNexusPath>/content/repositories/staging/</stagingNexusPath>

+		<sitePath>/content/sites/site/${project.groupId}/${project.artifactId}/${project.version}</sitePath>

+

+	</properties>

+	

+	<dependencies>

+		<dependency>

+			<groupId>org.onap.aaf.cadi</groupId>

+			<artifactId>cadi-aaf</artifactId>

+		</dependency>

+       

+	    <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-client</artifactId>

+        </dependency>

+

+	    <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-core</artifactId>

+        </dependency>

+

+	    <dependency>

+            <groupId>org.onap.aaf.authz</groupId>

+            <artifactId>authz-cmd</artifactId>

+        </dependency>

+

+		<dependency>

+			<groupId>com.att.aft</groupId>

+			<artifactId>dme2</artifactId>

+		</dependency>

+

+

+		<dependency>

+			<groupId>org.apache.jmeter</groupId>

+			<artifactId>ApacheJMeter_java</artifactId>

+			<version>2.11</version>

+		</dependency>

+		

+		<dependency>

+			<groupId>junit</groupId>

+			<artifactId>junit</artifactId>

+			<version>4.7</version>

+			<scope>test</scope>

+		</dependency>

+	</dependencies>

+

+	<build>

+		<pluginManagement>

+		  <plugins>

+			<plugin>

+	          <groupId>org.apache.maven.plugins</groupId>

+	          <artifactId>maven-failsafe-plugin</artifactId>

+	          <configuration>

+				<includes>

+	              <include>**/AAFJUnitTest.java</include>

+				</includes>

+			  </configuration>

+			</plugin>

+	

+			<plugin>

+	          <groupId>org.apache.maven.plugins</groupId>

+	          <artifactId>maven-surefire-plugin</artifactId>

+	          <configuration>

+				<excludes>

+	              <exclude>**/AAFJUnitTest.java</exclude>

+				</excludes>

+	          </configuration>

+			</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.sonatype.plugins</groupId>

+				<artifactId>nexus-staging-maven-plugin</artifactId>

+				<version>1.6.7</version>

+				<extensions>true</extensions>

+				<configuration>

+					<nexusUrl>${nexusproxy}</nexusUrl>

+					<stagingProfileId>176c31dfe190a</stagingProfileId>

+					<serverId>ecomp-staging</serverId>

+				</configuration>

+			</plugin> 

+		

+		

+			</plugins>

+		</pluginManagement>

+	</build>

+	<distributionManagement>

+		<repository>

+			<id>ecomp-releases</id>

+			<name>AAF Release Repository</name>

+			<url>${nexusproxy}${releaseNexusPath}</url>

+		</repository>

+		<snapshotRepository>

+			<id>ecomp-snapshots</id>

+			<name>AAF Snapshot Repository</name>

+			<url>${nexusproxy}${snapshotNexusPath}</url>

+		</snapshotRepository>

+		<site>

+			<id>ecomp-site</id>

+			<url>dav:${nexusproxy}${sitePath}</url>

+		</site>

+	</distributionManagement>

+<pluginRepositories>

+        <pluginRepository>

+            <id>onap-plugin-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots/</url>

+        </pluginRepository>

+    </pluginRepositories>

+	

+	<repositories>

+		<repository>

+			<id>central</id>

+			<name>Maven 2 repository 2</name>

+			<url>http://repo2.maven.org/maven2/</url>

+		</repository>

+		<repository>

+            <id>onap-jar-snapshots</id>

+            <url>https://nexus.onap.org/content/repositories/snapshots</url>

+        </repository>

+		<repository>

+			<id>spring-repo</id>

+			<name>Spring repo</name>

+			<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>

+		</repository>

+		<repository>

+			<id>repository.jboss.org-public</id>

+			<name>JBoss.org Maven repository</name>

+			<url>https://repository.jboss.org/nexus/content/groups/public</url>

+		</repository>

+	</repositories>

+</project>

diff --git a/authz-test/src/main/assemble/swm.xml b/authz-test/src/main/assemble/swm.xml
new file mode 100644
index 0000000..f2e8683
--- /dev/null
+++ b/authz-test/src/main/assemble/swm.xml
@@ -0,0 +1,34 @@
+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<assembly>

+	<id>swm</id>

+	<formats>

+		<format>zip</format>

+	</formats>

+	<baseDirectory>${artifactId}</baseDirectory>

+	<fileSets>

+		<fileSet>

+			<directory>target/swm</directory>

+		</fileSet>

+	</fileSets>

+</assembly>

diff --git a/authz-test/src/main/config/lrm-authz-service.xml b/authz-test/src/main/config/lrm-authz-service.xml
new file mode 100644
index 0000000..8cb7c9d
--- /dev/null
+++ b/authz-test/src/main/config/lrm-authz-service.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<ns2:ManagedResourceList xmlns:ns2="http://scld.att.com/lrm/util" xmlns="http://scld.att.com/lrm/commontypes" xmlns:ns3="http://scld.att.com/lrm/types">

+    <ns2:ManagedResource>

+        <ResourceDescriptor>

+            <ResourceName>com.att.authz._ARTIFACT_ID_</ResourceName>

+            <ResourceVersion>

+                <Major>_MAJOR_VER_</Major>

+                <Minor>_MINOR_VER_</Minor>

+                <Patch>_PATCH_VER_</Patch>                

+            </ResourceVersion>

+            <RouteOffer>_ROUTE_OFFER_</RouteOffer>

+        </ResourceDescriptor>

+        <ResourceType>Java</ResourceType>

+        <ResourcePath>com.att.authz.service.AuthzAPI</ResourcePath>

+        <ResourceProps>

+            <Tag>process.workdir</Tag>

+            <Value>_ROOT_DIR_</Value>

+        </ResourceProps>    	       

+        <ResourceProps>

+            <Tag>jvm.version</Tag>

+            <Value>1.6</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.args</Tag>

+            <Value>-DAFT_LATITUDE=_AFT_LATITUDE_ -DAFT_LONGITUDE=_AFT_LONGITUDE_ -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ -Dplatform=_SCLD_PLATFORM_ -Dcom.sun.jndi.ldap.connect.pool.maxsize=20  -Dcom.sun.jndi.ldap.connect.pool.prefsize=10 -Dcom.sun.jndi.ldap.connect.pool.timeout=3000 </Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.classpath</Tag>

+            <Value>_ROOT_DIR_/etc:_ROOT_DIR_/lib/*:</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.min</Tag>

+            <Value>512m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>jvm.heap.max</Tag>

+            <Value>1024m</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>start.class</Tag>

+            <Value>com.att.authz.service.AuthAPI</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stdout.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemOut.log</Value>

+        </ResourceProps>

+        <ResourceProps>

+            <Tag>stderr.redirect</Tag>

+            <Value>_ROOT_DIR_/logs/SystemErr.log</Value>

+        </ResourceProps>

+        <ResourceOSID>aft</ResourceOSID>

+        <ResourceStartType>AUTO</ResourceStartType>

+        <ResourceStartPriority>2</ResourceStartPriority>

+		<ResourceMinCount>_RESOURCE_MIN_COUNT_</ResourceMinCount>

+		<ResourceMaxCount>_RESOURCE_MAX_COUNT_</ResourceMaxCount>        

+        <ResourceSWMComponent>com.att.authz:_ARTIFACT_ID_</ResourceSWMComponent>

+        <ResourceSWMComponentVersion>_ARTIFACT_VERSION_</ResourceSWMComponentVersion>

+    </ns2:ManagedResource>

+</ns2:ManagedResourceList>

diff --git a/authz-test/src/main/config/tc.devl b/authz-test/src/main/config/tc.devl
new file mode 100644
index 0000000..5d3dcb0
--- /dev/null
+++ b/authz-test/src/main/config/tc.devl
@@ -0,0 +1,16 @@
+# Load Passwords needed
+function aafcli {
+  java \
+  -Daaf_id=testid \
+  -Daaf_pass=<pass> \
+  -Daaf_url=DMEServiceName=service=com.att.authz.AuthorizationService/version=_MAJOR_VER_._MINOR_VER_/envContext=_AFT_ENVIRONMENT_/routeOffer=_ROUTE_OFFER_ \
+  -DAFT_LATITUDE=_AFT_LATITUDE_ \
+  -DAFT_LONGITUDE=_AFT_LONGITUDE_ \
+  -DAFT_ENVIRONMENT=_AFT_ENVIRONMENT_ \
+  -Dtestid=<pass> \
+  -Dbogus=xxx \
+  -Dm12345=<pass> \
+  -jar \
+   /Volumes/Data/src/authz/authz-cmd/target/authz-cmd-2.0.2-SNAPSHOT-jar-with-dependencies.jar \
+   $*
+}
diff --git a/authz-test/src/main/scripts/cmds b/authz-test/src/main/scripts/cmds
new file mode 100644
index 0000000..ae44312
--- /dev/null
+++ b/authz-test/src/main/scripts/cmds
@@ -0,0 +1,20 @@
+# /bin/bash
+. ~/.bashrc
+function failed {
+     echo "FAILED TEST! " $*
+     exit 1
+}
+
+if [ "$1" != "" ] ; then 
+  for FILE in TestCases/$1/[0-9]*; do 
+     echo "*** "$FILE" ***"
+     cat $FILE
+     echo
+  done
+else
+  echo "Usage: cmds <TestCase>"
+fi
+
+
+
+exit 0
diff --git a/authz-test/src/main/scripts/copy b/authz-test/src/main/scripts/copy
new file mode 100644
index 0000000..59e86bf
--- /dev/null
+++ b/authz-test/src/main/scripts/copy
@@ -0,0 +1,17 @@
+# /bin/bash
+if [ "$2" != "" ] ; then 
+  if [ -e $2 ]; then
+     echo "$2 exists, copy aborted"
+     exit 1
+  fi
+  mkdir -p TestCases/$2
+  for FILE in TestCases/$1/*; do 
+     FILE2=`echo $FILE | sed -e "s/$1/$2/"`
+     echo $FILE2
+     sed -e "s/$1/$2/g" $FILE > $FILE2
+  done
+else
+  echo 'Usage: copy <Source TestCase> <Target TestCase>'
+fi
+
+exit 0
diff --git a/authz-test/src/main/scripts/csv b/authz-test/src/main/scripts/csv
new file mode 100644
index 0000000..e8712ce
--- /dev/null
+++ b/authz-test/src/main/scripts/csv
@@ -0,0 +1,14 @@
+# /bin/bash
+cd TestCases
+if [ "$1" == "" ]; then
+   DIRS=`ls -d TC*`
+else
+   DIRS=$1
+fi
+
+echo '"Test Case","Description"'
+for DIR in $DIRS; do 
+  grep -h "^# $DIR" $DIR/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /,"/' -e 's/$/"/'
+done
+cd ..
+exit 0
diff --git a/authz-test/src/main/scripts/rpt1 b/authz-test/src/main/scripts/rpt1
new file mode 100644
index 0000000..61d149d
--- /dev/null
+++ b/authz-test/src/main/scripts/rpt1
@@ -0,0 +1,23 @@
+# /bin/bash
+if [ "$1" == "" ]; then
+  echo "Usage: rpt1 <TestCase>"
+  exit 1
+fi
+
+cd TestCases
+echo "**"
+echo "** TC Group: $1"
+echo "** Date    : "`date`
+echo "** By      : "`who | cut -d " " -f 1`
+echo "**"
+echo ""
+echo "-- Description --"
+cat $1/Description 
+echo -- Positive Cases --
+grep -h "^# $1.*OK " $1/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /  	/'
+echo
+echo -- Negative Cases --
+grep -h "^# $1.*FAIL " $1/[0-9]* | cut -d ' ' -f 2- | sed -e 's/ /	/'
+
+cd ..
+exit 0
diff --git a/authz-test/src/main/scripts/rpt2 b/authz-test/src/main/scripts/rpt2
new file mode 100644
index 0000000..2c6b6f7
--- /dev/null
+++ b/authz-test/src/main/scripts/rpt2
@@ -0,0 +1,12 @@
+# /bin/bash
+if [ "$1" == "" ]; then
+  echo "Usage: rpt2 <TestCase>"
+  exit 1
+fi
+
+bin/rpt1 TC_NS1 
+echo ""
+echo "-- Results"
+echo ""
+bin/tc TC_NS1
+
diff --git a/authz-test/src/main/scripts/tc b/authz-test/src/main/scripts/tc
new file mode 100644
index 0000000..1125849
--- /dev/null
+++ b/authz-test/src/main/scripts/tc
@@ -0,0 +1,37 @@
+# /bin/bash
+mkdir -p runs
+function failed {
+     echo "FAILED TEST! $*"
+     exit 1
+}
+
+if [ "$1" == "" ]; then
+  DIRS=`find TestCases -type d -name "TC_*" -maxdepth 1 | sed "s/^TestCases\///"`
+  if [ "$DIRS" == "" ] ; then 
+    echo "Usage: tc <TestCase> [expected]"
+    echo "  expected - create the expected response for future comparison"
+    exit 1
+  fi
+else
+  DIRS=$1
+  shift
+fi
+
+for TC in $DIRS; do
+  if [ "$1" = "expected" ]; then
+    SUFFIX=$1
+    cat TestCases/$TC/[0-9]* | aafcli -i 2>&1 | tee TestCases/expected/$TC.$SUFFIX
+  elif [ -d "TestCases/$TC" ]; then
+    SUFFIX=`date "+%Y-%m-%d_%H:%M:%S"`
+    cat TestCases/$TC/[0-9]* | aafcli -i 2>&1 | tee runs/$TC.$SUFFIX > /dev/null
+  
+    diff runs/$TC.$SUFFIX TestCases/expected/$TC.expected || failed "[$TC.$SUFFIX]"
+    echo "SUCCESS! [$TC.$SUFFIX]"
+  else
+    echo missed dir
+exit
+    cat $TC | aafcli -i 
+  fi
+done
+
+exit 0
diff --git a/authz-test/src/main/swm/common/deinstall.sh b/authz-test/src/main/swm/common/deinstall.sh
new file mode 100644
index 0000000..740564c
--- /dev/null
+++ b/authz-test/src/main/swm/common/deinstall.sh
@@ -0,0 +1,40 @@
+#!/bin/sh

+##############################################################################

+# - Copyright 2012, 2016 AT&T Intellectual Properties

+##############################################################################
+umask 022

+ROOT_DIR=${INSTALL_ROOT}/${distFilesRootDirPath}

+

+# Grab the IID of all resources running under the name and same version(s) we're working on and stop those instances

+${LRM_HOME}/bin/lrmcli -running | \

+	grep ${artifactId} | \

+	grep ${version} | \

+	cut -f1 | \

+while read _iid

+do

+	if [ -n "${_iid}" ]; then

+		${LRM_HOME}/bin/lrmcli -shutdown -iid ${_iid} | grep SUCCESS

+		if [ $? -ne 0 ]; then

+			echo "$LRMID-{_iid} Shutdown failed"

+		fi

+	fi

+done

+	

+# Grab the resources configured under the name and same version we're working on and delete those instances

+${LRM_HOME}/bin/lrmcli -configured | \

+	grep ${artifactId} | \

+	grep ${version} | \

+	cut -f1,2,3 | \

+while read _name _version _routeoffer

+do

+	if [ -n "${_name}" ]; then

+		${LRM_HOME}/bin/lrmcli -delete -name ${_name} -version ${_version} -routeoffer ${_routeoffer} | grep SUCCESS

+		if [ $? -ne 0 ]; then

+			echo "${_version} Delete failed"

+		fi

+	fi

+done	

+

+rm -rf ${ROOT_DIR}

+

+exit 0

diff --git a/authz-test/src/main/swm/common/install.sh b/authz-test/src/main/swm/common/install.sh
new file mode 100644
index 0000000..0c38612
--- /dev/null
+++ b/authz-test/src/main/swm/common/install.sh
@@ -0,0 +1,144 @@
+#!/bin/sh
+##############################################################################
+# - Copyright 2012, 2016 AT&T Intellectual Properties
+##############################################################################
+umask 022
+ROOT_DIR=${INSTALL_ROOT}/${distFilesRootDirPath}
+LOGGING_PROP_FILE=${ROOT_DIR}/etc/log4j.properties
+RUN_FILE=${ROOT_DIR}/etc/tconn.sh
+
+cd ${ROOT_DIR}
+
+mkdir -p logs || fail 1 "Error on creating the logs directory."
+mkdir -p back || fail 1 "Error on creating the back directory."
+chmod 777 back || fail 1 "Error on creating the back directory."
+
+# 
+# Some Functions that Vastly cleanup this install file...
+# You wouldn't believe how ugly it was before.  Unreadable... JG 
+#
+fail() {
+	rc=$1
+	shift;
+    echo "ERROR: $@"
+    exit $rc
+}
+
+#
+# Set the "SED" replacement for this Variable.  Error if missing
+# Note that Variable in the Template is surrounded by "_" i.e. _ROOT_DIR_
+#   Replacement Name
+#   Value
+#
+required() {
+	if [ -z "$2" ]; then
+	  ERRS+="\n\t$1 must be set for this installation"
+	fi
+	SED_E+=" -e s|$1|$2|g"
+}
+
+#
+# Set the "SED" replacement for this Variable. Use Default (3rd parm) if missing
+# Note that Variable in the Template is surrounded by "_" i.e. _ROOT_DIR_
+#   Replacement Name
+#   Value
+#   Default Value
+#
+default() {
+    if [ -z "$2" ]; then
+    	SED_E+=" -e s|$1|$3|g"
+    else 
+    	SED_E+=" -e s|$1|$2|g"
+    fi
+}
+
+# Linux requires this.  Mac blows with it.  Who knows if Windoze even does SED
+if [ -z "$SED_OPTS" ]; then
+	SED_E+=" -c "
+else
+	SED_E+=$SED_OPTS;
+fi 
+
+
+# 
+# Use "default" function if there is a property that isn't required, but can be defaulted
+# use "required" function if the property must be set by the environment
+#
+	required _ROOT_DIR_ ${ROOT_DIR}
+	default _COMMON_DIR_ ${COMMON_DIR} ${ROOT_DIR}/../../common
+	required _AFT_ENVIRONMENT_ ${AFT_ENVIRONMENT}
+	required _ENV_CONTEXT_ ${ENV_CONTEXT}
+	required _HOSTNAME_ ${HOSTNAME}
+	required _ARTIFACT_ID_ ${artifactId}
+	required _ARTIFACT_VERSION_ ${version}
+	
+	# Specifics for Service
+	if [ "${artifactId}" = "authz-service" ]; then
+		default _AUTHZ_SERVICE_PORT_ ${PORT} 0
+		required _AUTHZ_CASS_CLUSTERS_ ${AUTHZ_CASS_CLUSTERS}
+		required _AUTHZ_CASS_PORT_ ${AUTHZ_CASS_PORT}
+		required _AUTHZ_CASS_PWD_ ${AUTHZ_CASS_PWD}
+		default _AUTHZ_CASS_USER_ ${AUTHZ_CASS_USER} authz
+		required _AUTHZ_KEYSTORE_PASSWORD_ ${AUTHZ_KEYSTORE_PASSWORD}
+		required _AUTHZ_KEY_PASSWORD_ ${AUTHZ_KEY_PASSWORD}
+		required _SCLD_PLATFORM_ ${SCLD_PLATFORM}
+	fi
+
+	default _EMAIL_FROM_ ${EMAIL_FROM} authz@ems.att.com
+    default _EMAIL_HOST_ ${EMAIL_HOST} mailhost.att.com
+	default _ROUTE_OFFER_ ${ROUTE_OFFER} BAU_SE
+	default _DME_TIMEOUT_ ${DME_TIMEOUT} 3000
+
+	# Choose defaults for log level and logfile size
+	if [ "${SCLD_PLATFORM}" = "PROD" ]; then
+	        LOG4J_LEVEL=WARN
+	fi
+	default _LOG4J_LEVEL_ ${LOG4J_LEVEL} INFO  
+	default _LOG4J_SIZE_ ${LOG4J_SIZE} 10000KB
+	default _LOG_DIR_ ${LOG_DIR} ${ROOT_DIR}/logs
+	default _MAX_LOG_FILE_SIZE_ ${MAX_LOG_FILE_SIZE} 10000KB
+	default _MAX_LOG_FILE_BACKUP_COUNT_ ${MAX_LOG_FILE_BACKUP_COUNT} 7
+	default _RESOURCE_MIN_COUNT_ ${RESOURCE_MIN_COUNT} 1
+	default _RESOURCE_MAX_COUNT_ ${RESOURCE_MAX_COUNT} 1
+
+	required _LOGGING_PROP_FILE_ ${LOGGING_PROP_FILE}
+	required _AFT_LATITUDE_ ${LATITUDE}
+	required _AFT_LONGITUDE_ ${LONGITUDE}
+	required _HOSTNAME_ ${HOSTNAME}
+	
+	# Divide up Version
+	default _MAJOR_VER_ "`expr ${version} : '\([0-9]*\)\..*'`"
+	default _MINOR_VER_ "`expr ${version} : '[0-9]*\.\([0-9]*\)\..*'`"
+	default _PATCH_VER_ "`expr ${version} : '[0-9]\.[0-9]*\.\(.*\)'`"
+
+	
+
+# Now Fail if Required items are not set... 
+# Report all of them at once!
+if [ "${ERRS}" != "" ] ; then
+	fail 1 "${ERRS}"
+fi
+
+#echo ${SED_E}
+
+for i in ${PROPERTIES_FILE} ${LRM_XML} ${LOGGING_PROP_FILE} ${RUN_FILE} ; do
+  if [ -r ${i} ]; then
+	  if [ -w ${i} ]; then
+#	  	echo ${i}
+	     sed ${SED_E} -i'.sed' ${i} || fail 8 "could not sed ${i} "
+	     mv -f ${i}.sed ${ROOT_DIR}/back
+	   fi
+	fi
+done
+
+#
+# Add the resource to LRM using the newly created/substituted XML file.
+#
+# Note: No LRM for authz-test
+#if [ -r ${LRM_XML} ]; then
+#	${LRM_HOME}/bin/lrmcli -addOrUpgrade -file ${LRM_XML} || fail 1 "Add to LRM Failed"
+#	${LRM_HOME}/bin/lrmcli -start -name com.att.authz.${artifactId} -version ${version} -routeoffer ${ROUTE_OFFER} | grep SUCCESS
+#fi
+#
+# Note: Must exit 0 or, it will be exit default 1 and fail
+exit 0
diff --git a/authz-test/src/main/swm/deinstall/postproc/post_proc b/authz-test/src/main/swm/deinstall/postproc/post_proc
new file mode 100644
index 0000000..beec0a2
--- /dev/null
+++ b/authz-test/src/main/swm/deinstall/postproc/post_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+#!/bin/sh
+exit 0
\ No newline at end of file
diff --git a/authz-test/src/main/swm/deinstall/preproc/pre_proc b/authz-test/src/main/swm/deinstall/preproc/pre_proc
new file mode 100644
index 0000000..2a6a529
--- /dev/null
+++ b/authz-test/src/main/swm/deinstall/preproc/pre_proc
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec sh -x ../../common/deinstall.sh
diff --git a/authz-test/src/main/swm/descriptor.xml b/authz-test/src/main/swm/descriptor.xml
new file mode 100644
index 0000000..625ed2d
--- /dev/null
+++ b/authz-test/src/main/swm/descriptor.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>

+<!--

+  ============LICENSE_START====================================================

+  * org.onap.aaf

+  * ===========================================================================

+  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+  * ===========================================================================

+  * Licensed under the Apache License, Version 2.0 (the "License");

+  * you may not use this file except in compliance with the License.

+  * You may obtain a copy of the License at

+  * 

+   *      http://www.apache.org/licenses/LICENSE-2.0

+  * 

+   * Unless required by applicable law or agreed to in writing, software

+  * distributed under the License is distributed on an "AS IS" BASIS,

+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+  * See the License for the specific language governing permissions and

+  * limitations under the License.

+  * ============LICENSE_END====================================================

+  *

+  * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+  *

+-->

+<descriptor version="1" xmlns="http://aft.att.com/swm/descriptor">

+	<platforms>

+		<platform architecture="*" os="*" osVersions="*"/> 

+	</platforms>

+	<paths>

+		<path name="/opt/app/aft/auth/${artifactId}/${version}" type="d" user="aft" group="aft" permissions="0755" recursive="true"/>

+	</paths>

+	<actions>

+		<action type="INIT">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="INST">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="DINST">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+		<action type="FALL">

+			<proc stage="PRE" user="aft" group="aft"/>

+			<proc stage="POST" user="aft" group="aft"/>

+		</action>

+	</actions>

+</descriptor>

diff --git a/authz-test/src/main/swm/fallback/postproc/post_proc b/authz-test/src/main/swm/fallback/postproc/post_proc
new file mode 100644
index 0000000..3eb8e6d
--- /dev/null
+++ b/authz-test/src/main/swm/fallback/postproc/post_proc
@@ -0,0 +1,6 @@
+#!/bin/sh

+######################################################################

+# $RCSfile$ - $Revision$

+# Copyright 2012 AT&T Intellectual Property. All rights reserved.

+######################################################################

+exec sh -x ../../common/install.sh
\ No newline at end of file
diff --git a/authz-test/src/main/swm/fallback/preproc/pre_proc b/authz-test/src/main/swm/fallback/preproc/pre_proc
new file mode 100644
index 0000000..0895847
--- /dev/null
+++ b/authz-test/src/main/swm/fallback/preproc/pre_proc
@@ -0,0 +1,6 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+exit 0
\ No newline at end of file
diff --git a/authz-test/src/main/swm/initinst/postproc/post_proc b/authz-test/src/main/swm/initinst/postproc/post_proc
new file mode 100644
index 0000000..1f27b41
--- /dev/null
+++ b/authz-test/src/main/swm/initinst/postproc/post_proc
@@ -0,0 +1,6 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+exec sh -x ../../common/install.sh
diff --git a/authz-test/src/main/swm/initinst/preproc/pre_proc b/authz-test/src/main/swm/initinst/preproc/pre_proc
new file mode 100644
index 0000000..beec0a2
--- /dev/null
+++ b/authz-test/src/main/swm/initinst/preproc/pre_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+#!/bin/sh
+exit 0
\ No newline at end of file
diff --git a/authz-test/src/main/swm/install/postproc/post_proc b/authz-test/src/main/swm/install/postproc/post_proc
new file mode 100644
index 0000000..4cdbce1
--- /dev/null
+++ b/authz-test/src/main/swm/install/postproc/post_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+
+exec sh -x ../../common/install.sh
diff --git a/authz-test/src/main/swm/install/preproc/pre_proc b/authz-test/src/main/swm/install/preproc/pre_proc
new file mode 100644
index 0000000..807ebdc
--- /dev/null
+++ b/authz-test/src/main/swm/install/preproc/pre_proc
@@ -0,0 +1,7 @@
+#!/bin/sh
+######################################################################
+# $RCSfile$ - $Revision$
+# Copyright 2012 AT&T Intellectual Property. All rights reserved.
+######################################################################
+
+exit 0
diff --git a/authz-test/src/main/swm/packageNotes.txt b/authz-test/src/main/swm/packageNotes.txt
new file mode 100644
index 0000000..cc8c7ee
--- /dev/null
+++ b/authz-test/src/main/swm/packageNotes.txt
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------

+# ============LICENSE_START====================================================

+# * org.onap.aaf

+# * ===========================================================================

+# * Copyright © 2017 AT&T Intellectual Property. All rights reserved.

+# * ===========================================================================

+# * Licensed under the Apache License, Version 2.0 (the "License");

+# * you may not use this file except in compliance with the License.

+# * You may obtain a copy of the License at

+# * 

+#  *      http://www.apache.org/licenses/LICENSE-2.0

+# * 

+#  * Unless required by applicable law or agreed to in writing, software

+# * distributed under the License is distributed on an "AS IS" BASIS,

+# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+# * See the License for the specific language governing permissions and

+# * limitations under the License.

+# * ============LICENSE_END====================================================

+# *

+# * ECOMP is a trademark and service mark of AT&T Intellectual Property.

+# *

+#-------------------------------------------------------------------------------

+The following two commands can be used to create and approve a SWM installation package.

+

+These steps assume:

+	1.  The component has been added in SWM

+	2.  The java6 directory resides, by itself, under the directory '${artifactId}-${version}'

+	3.  The SWM client is executed from the same directory containing '${artifactId}-${version}'

+

+

+    attuid@swmcli- --> component pkgcreate -c ${groupId}:${artifactId}:${version} -d ${artifactId}-${version}

+    attuid@swmcli- --> component pkgapprove -c ${groupId}:${artifactId}:${version}

diff --git a/dme2reg/service=org.onap.aaf.authz.AuthorizationService/version=2.0/envContext=DEV/.gitignore b/dme2reg/service=org.onap.aaf.authz.AuthorizationService/version=2.0/envContext=DEV/.gitignore
new file mode 100644
index 0000000..25b6eed
--- /dev/null
+++ b/dme2reg/service=org.onap.aaf.authz.AuthorizationService/version=2.0/envContext=DEV/.gitignore
@@ -0,0 +1,2 @@
+/routeOffer=BAU_SE.lock
+/routeOffer=BAU_SE.txt
diff --git a/opt/app/aaf/common/.gitignore b/opt/app/aaf/common/.gitignore
new file mode 100644
index 0000000..4e8dea1
--- /dev/null
+++ b/opt/app/aaf/common/.gitignore
@@ -0,0 +1,4 @@
+/com.osaaf.common.props
+/com.osaaf.keyfile
+/com.osaaf.props
+/mylocal.common.props
diff --git a/opt/app/aaf/common/README.txt b/opt/app/aaf/common/README.txt
new file mode 100644
index 0000000..4de4f15
--- /dev/null
+++ b/opt/app/aaf/common/README.txt
@@ -0,0 +1,15 @@
+# Initial instructions for Common Directory
+
+1) Generate a Keyfile
+	a) From the "Cadi" Lib directory
+		java -jar <CADI DIRECTORY>/lib/cadi_core*.jar keygen com.osaaf.keyfile
+2) "cp" com.osaaf.common.props.sample to a locally named file
+	a) It is best to replace relative paths with canonical paths
+	a) Add your Cassandra Connection info.
+	b) For your Password, do (from "Cadi Lib" again):
+		java -jar <CADI DIRECTORY>/lib/cadi_core*.jar digest com.osaaf.keyfile
+		Prepend "enc:" to the encrypted password
+3) "ln -s" the locally named file to com.osaaf.common.props
+4) "cp" com.osaaf.props.sample to com.osaaf.props
+	Note: This file will be replaced by Certificate Manager if used
+	a) Update with appropriate "Certificate Manger" URL, if used
diff --git a/opt/app/aaf/common/com.osaaf.common.props.sample b/opt/app/aaf/common/com.osaaf.common.props.sample
new file mode 100644
index 0000000..0081413
--- /dev/null
+++ b/opt/app/aaf/common/com.osaaf.common.props.sample
@@ -0,0 +1,78 @@
+############################################################
+# Properties Written by Jonathan Gathman
+#   on 2016-08-12T04:17:59.628-0500
+# These properties encapsulate the Verisign Public Certificates
+############################################################
+# DEVELOPER ONLY SETTING!!!!!  DO NOT USE on ANY BOX other than your Developer box, and it
+# would be better if you got a Cert for that, and remove this!  There is nothing stupider than
+# an unsecured Security Service.
+cadi_trust_all_x509=true
+
+# Public (i.e. Verisign) Key stores.
+# AFT_DME2_KEYSTORE=
+# AFT_DME2_KEYSTORE_PASSWORD=
+# AFT_DME2_KEY_PASSWORD=
+# cadi_truststore=
+# cadi_truststore_password=
+
+# Standard for this App/Machine
+aaf_env=DEV
+aaf_data_dir=../data
+cadi_loglevel=WARN
+aaf_id=<osaaf's Application Identity>
+aaf_password=enc:<Encrypted Password, use java -jar cadi-core*.jar>
+
+aaf_conn_timeout=6000
+aaf_timeout=10000
+aaf_user_expires=600000
+aaf_clean_interval=45000
+aaf_refresh_trigger_count=3
+aaf_high_count=30000
+
+# Basic Auth
+aaf_default_realm=osaaf.com
+basic_realm=osaaf.com
+basic_warn=false
+localhost_deny=false
+
+# Cassandra
+# IP:Cass DataCenter:Latitude:Longitude,IP....
+# cassandra.clusters=127.0.0.1:dc1:32.780140:-96.800451,127.0.0.2:dc1:32.780140:-96.800451
+# cassandra.clusters.port=9042
+# cassandra.clusters.user=
+# cassandra.clusters.password=enc:<encrypted>
+## Exceptions from Cassandra which require resetting the Cassandra Connections
+cassandra.reset.exceptions=com.datastax.driver.core.exceptions.NoHostAvailableException:"no host was tried":"Connection has been closed"
+
+# Consistency Settings
+cassandra.writeConsistency.ns=LOCAL_QUORUM
+cassandra.writeConsistency.perm=LOCAL_QUORUM
+cassandra.writeConsistency.role=LOCAL_QUORUM
+cassandra.writeConsistency.user_role=LOCAL_QUORUM
+cassandra.writeConsistency.cred=LOCAL_QUORUM
+cassandra.writeConsistency.ns_attrib=LOCAL_QUORUM
+
+## Supported Plugin Organizational Units
+Organization.com.osaaf=com.osaaf.defOrg.DefaultOrg
+
+## Email Server settings for Def Organization.
+#Sender's email ID needs to be mentioned
+com.osaaf.mailFromUserId=mailid@bogus.com
+com.osaaf.supportEmail=support@bogus.com
+com.osaaf.mailHost=smtp.bogus.com
+
+# Standard AAF DME2 Props
+AFT_DME2_REMOVE_PERSISTENT_CACHE_ON_STARTUP=TRUE
+AFT_DME2_DISABLE_PERSISTENT_CACHE=TRUE
+AFT_DME2_DISABLE_PERSISTENT_CACHE_LOAD=TRUE
+
+## SSL OPTIONAL ONLY IN DEVELOPMENT PC/Local... WHATEVER YOU DO, don't use this on any box than your local PC
+AFT_DME2_SSL_ENABLE=false
+# for when you turn on SSL... Only TLSv1.1+ is secure as of 2016
+AFT_DME2_SSL_WANT_CLIENT_AUTH=TRUE
+AFT_DME2_SSL_INCLUDE_PROTOCOLS=TLSv1.1,TLSv1.2
+AFT_DME2_SSL_VALIDATE_CERTS=FALSE
+AFT_DME2_CLIENT_IGNORE_SSL_CONFIG=false
+
+## Extra CA Trusts, for Certifiate Manager to build truststore with external CAs
+cm_trust_cas=VerisignG3_CA.cer;VerisignG4_CA.cer;VerisignG5_CA.cer
diff --git a/opt/app/aaf/common/com.osaaf.props.sample b/opt/app/aaf/common/com.osaaf.props.sample
new file mode 100644
index 0000000..59948ef
--- /dev/null
+++ b/opt/app/aaf/common/com.osaaf.props.sample
@@ -0,0 +1,9 @@
+############################################################
+# Initial File for Generating
+#   on 2016-10-26T06:56:19.905-0500
+# @copyright 2016, AT&T
+############################################################
+cm_url=https://<certificate manager host>:8150
+hostname=<your host>
+cadi_x509_issuers=CN=ATT CADI Issuing CA - Test 01, OU=CSO, O=ATT, C=US
+cadi_keyfile=../common/com.osaaf.keyfile
diff --git a/opt/app/aaf/data/identities.dat b/opt/app/aaf/data/identities.dat
new file mode 100644
index 0000000..98bf99a
--- /dev/null
+++ b/opt/app/aaf/data/identities.dat
@@ -0,0 +1,7 @@
+iowna|Ima D. Owner|Ima|Owner|314-123-2000|ima.d.owner@osaaf.com|e|
+mmanager|Mark D. Manager|Mark|Manager|314-123-1234|mark.d.manager@osaaf.com|e|iowna
+bdevl|Robert D. Developer|Bob|Developer|314-123-1235|bob.d.develper@osaaf.com|e|mmanager
+mmarket|Mary D. Marketer|Mary|Marketer|314-123-1236|mary.d.marketer@osaaf.com|e|mmanager
+ccontra|Clarice D. Contractor|Clarice|Contractor|314-123-1237|clarice.d.contractor@osaaf.com|c|mmanager
+iretired|Ira Lee M. Retired|Ira|Retired|314-123-1238|clarice.d.contractor@osaaf.com|n|mmanager
+osaaf|ID of AAF|||||a|bdevl
diff --git a/opt/app/aaf/data/identities.idx b/opt/app/aaf/data/identities.idx
new file mode 100644
index 0000000..78fc0a5
--- /dev/null
+++ b/opt/app/aaf/data/identities.idx
Binary files differ
diff --git a/pom.xml b/pom.xml
index 5caa668..552017c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,19 +50,13 @@
 		packaged.  This prevents duplication of these common artifacts, plugins, and 
 		other settings and provides a single place to support this configuration.
 	</description>
-		 <parent>
-		<groupId>org.onap.oparent</groupId>
-		<artifactId>oparent</artifactId>
-		<version>1.0.0-SNAPSHOT</version>
-	</parent>
 	<properties>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<skipTests>false</skipTests>
-		<project.interfaceVersion>2.6</project.interfaceVersion>
+		<project.interfaceVersion>1.0.0-SNAPSHOT</project.interfaceVersion>
 		<project.innoVersion>1.0.0-SNAPSHOT</project.innoVersion>
 		<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>
 		<project.dme2Version>3.1.200</project.dme2Version>
-			<project.cadiVersion>1.0.0-SNAPSHOT</project.cadiVersion>
 		<nexusproxy>https://nexus.onap.org</nexusproxy>
 		<snapshotNexusPath>/content/repositories/snapshots/</snapshotNexusPath>
 		<releaseNexusPath>/content/repositories/releases/</releaseNexusPath>
@@ -91,6 +85,43 @@
 						</configuration>        
 				</plugin>
 	
+				<plugin>
+				  <groupId>org.apache.maven.plugins</groupId>
+				  <artifactId>maven-surefire-plugin</artifactId>
+				  <version>2.17</version>
+				  <configuration>
+					<skipTests>${skipTests}</skipTests>
+					<includes>
+					  <include>**/JU*.java</include>
+					</includes>
+					<excludes>
+					<exclude>**/JU_DataFile.java</exclude>
+					<exclude>**/JU_ArtiDAO.java</exclude>
+					<exclude>**/JU_CertDAO.java</exclude>
+					<exclude>**/JU_FastCalling.java</exclude>
+					<exclude>**/JU_NsDAO.java</exclude>
+					  <!-- <exclude>**/authz-cass/**</exclude> -->
+					  <!-- <exclude>**/JU_UseCase1.java</exclude> -->
+					  <exclude>**/JU_RoleDAO.java</exclude>
+					  <exclude>**/JU_PermDAO.java</exclude>
+					   <exclude>**/JU_Question.java</exclude> 
+					  <!-- <exclude>**/JU_NS.java</exclude> -->
+					  <exclude>**/JU_HistoryDAO.java</exclude>				  
+					  <exclude>**/JU_DelegateDAO.java</exclude>
+					  <exclude>**/JU_CredDAO.java</exclude>
+					  <exclude>**/JU_CacheInfoDAO.java</exclude>
+					  <exclude>**/JU_ApprovalDAO.java</exclude>
+					  <exclude>**/JU_Define.java</exclude>
+					  <exclude>**/JU_AuthzTransFilter.java</exclude>
+					  <exclude>**/JU_CachingFileAccess.java</exclude>
+					  <!-- <exclude>**/AbsServiceTest.java</exclude> -->
+					  <exclude>**/JU_DefaultOrg.java</exclude>
+					  <!-- <exclude>**/JU_Perm_2_0*.java</exclude> -->
+					  <!-- <exclude>**/JU_Role_2_0*.java</exclude>				   -->
+					</excludes>
+	
+				  </configuration>
+				</plugin>
 	
 				<plugin>
 					<groupId>org.codehaus.mojo</groupId>
@@ -126,7 +157,41 @@
 					</execution>
 				  </executions>
 				</plugin>
-				
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-jarsigner-plugin</artifactId>
+					<version>1.2</version>
+					<executions>
+						<execution>
+							<id>sign</id>
+							<goals>
+								<goal>sign</goal>
+							</goals>
+							<configuration>
+								<!--  skip>${skipSigning}</skip -->
+								<archive>target/${project.artifactId}-${project.version}.jar</archive>
+							</configuration>
+						</execution>
+						<execution>
+							<id>verify</id>
+							<goals>
+								<goal>verify</goal>
+							</goals>
+							<configuration>
+								<archive>target/${project.artifactId}-${project.version}.jar</archive>
+							</configuration>
+						</execution>
+					</executions>
+					<configuration>
+						<skip>true</skip>
+						<alias>aaf</alias>
+						<keystore>/Volumes/Data/src/cadi/keys/aaf_cadi.jks</keystore>
+						<storepass>Surprise!</storepass>
+						<keypass>Surprise!</keypass>
+						<verbose>true</verbose>
+						<certs>true</certs>
+					</configuration>
+				</plugin>
 				
 							<plugin>
 			<groupId>org.apache.maven.plugins</groupId>
@@ -158,6 +223,7 @@
 			</execution>
 		      </executions>
 		    </plugin>
+
 			
 		<plugin>
 				<groupId>org.codehaus.mojo</groupId>
@@ -217,9 +283,22 @@
 	</dependencies>    	
 
 	<modules>
-
+		<!-- 
+		   <module> auth-client</module>
+		   complile manually with mvn -N independently
+		-->
 		<module>authz-client</module>
-	
+		<module>authz-core</module>
+		<module>authz-cass</module>
+		<module>authz-defOrg</module>
+		<module>authz-service</module>
+ 		<module>authz-cmd</module>
+ 		<!--  <module>authz-batch</module>-->
+ 		<module>authz-test</module>
+ 		<!--  <module>authz-gui</module> -->
+ 		<module>authz-gw</module>
+ 		<module>authz-certman</module>
+ 		<module>authz-fs</module>
  	</modules>
 	
 	<dependencyManagement>
@@ -248,8 +327,68 @@
 				<version>${project.innoVersion}</version>
 			</dependency>
 			
+			<dependency>
+				<groupId>org.onap.aaf.cadi</groupId>
+				<artifactId>cadi-core</artifactId>
+				<version>${project.cadiVersion}</version>
+			</dependency>
 
+			<dependency>
+				<groupId>org.onap.aaf.cadi</groupId>
+				<artifactId>cadi-client</artifactId>
+				<version>${project.cadiVersion}</version>
+			</dependency>
 			
+			
+			<dependency>
+				<groupId>org.onap.aaf.cadi</groupId>
+				<artifactId>cadi-aaf</artifactId>
+				<version>${project.cadiVersion}</version>
+				<exclusions>
+			      <exclusion> 
+					<groupId>org.apache.cassandra</groupId>
+		    		<artifactId>cassandra-all</artifactId>
+    		      </exclusion>
+			    </exclusions> 
+			</dependency>
+			
+			<dependency>
+				<groupId>org.onap.aaf.authz</groupId>
+				<artifactId>authz-client</artifactId>
+				<version>${project.interfaceVersion}</version>
+			</dependency>
+			
+			
+			<dependency>
+				<groupId>org.onap.aaf.authz</groupId>
+				<artifactId>authz-core</artifactId>
+				<version>${project.version}</version>
+			</dependency>
+			
+			<dependency>
+	            <groupId>org.onap.aaf.authz</groupId>
+	            <artifactId>authz-cass</artifactId>
+				<version>${project.version}</version>
+	        </dependency>
+	        
+	        <dependency>
+				<groupId>org.onap.aaf.authz</groupId>
+				<artifactId>authz-batch</artifactId>
+				<version>${project.interfaceVersion}</version>
+			</dependency>
+	    
+
+
+		    <dependency>
+	            <groupId>org.onap.aaf.authz</groupId>
+	            <artifactId>authz-cmd</artifactId>
+				<version>${project.version}</version>
+	        </dependency>
+	        <dependency>
+	            <groupId>org.onap.aaf.authz</groupId>
+	            <artifactId>authz-gw</artifactId>
+				<version>${project.version}</version>
+	        </dependency>
 
 			<dependency>
 				<groupId>com.att.aft</groupId>
@@ -317,8 +456,7 @@
 			
 		</dependencies>
 	</dependencyManagement>
-
-<distributionManagement>
+	<distributionManagement>
 		<repository>
 			<id>ecomp-releases</id>
 			<name>AAF Release Repository</name>