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-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);

+		}

+	}

+

+}