summaryrefslogtreecommitdiffstats
path: root/auth/auth-core
diff options
context:
space:
mode:
Diffstat (limited to 'auth/auth-core')
-rw-r--r--auth/auth-core/.gitignore5
-rw-r--r--auth/auth-core/pom.xml104
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/cache/Cache.java200
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java82
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzEnv.java310
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java78
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java181
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java216
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransOnlyFilter.java86
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java234
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/layer/DirectIntrospectImpl.java26
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/layer/FacadeImpl.java42
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/layer/Result.java328
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/local/AbsData.java206
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/local/DataFile.java190
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/local/TextIndex.java256
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/org/EmailWarnings.java33
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/org/Executor.java34
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java515
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationException.java52
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationFactory.java125
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Acceptor.java169
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java564
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CodeSetter.java52
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Content.java115
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpCode.java118
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpMethods.java29
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Match.java211
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Pair.java44
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java154
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Route.java141
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RouteReport.java33
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Routes.java89
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java156
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransOnlyFilter.java77
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TypedCode.java269
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Version.java93
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/doc/ApiDoc.java40
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsService.java156
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java95
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java255
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/server/ServiceStarter.java26
-rw-r--r--auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java204
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/common/test/JU_Define.java66
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzEnv.java174
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransFilter.java130
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransImpl.java169
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransOnlyFilter.java121
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_NullTrans.java273
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/layer/test/JU_Result.java58
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_DataFile.java70
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_TextIndex.java76
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationException.java48
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationFactory.java64
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/CredCompare.java64
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/JU_RequestCheck.java42
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/MultiCompare.java69
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSAttribCompare.java93
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSCompare.java75
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/PermCompare.java66
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RoleCompare.java62
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RolePermCompare.java69
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RosettaCompare.java66
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/UserRoleCompare.java62
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch.java173
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch1.java164
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterRoute.java33
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CachingFileAccess.java184
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CodeSetter.java73
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content.java661
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content1.java130
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Pair.java47
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Route.java38
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_RouteReport.java40
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Routes.java72
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_TypedCode.java106
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Version.java70
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/server/test/JU_JettyServiceStarter.java95
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/util/test/JU_Mask.java71
-rw-r--r--auth/auth-core/src/test/java/org/onap/aaf/auth/validation/test/JU_Validator.java204
-rw-r--r--auth/auth-core/test/sample.identities.dat27
81 files changed, 10498 insertions, 0 deletions
diff --git a/auth/auth-core/.gitignore b/auth/auth-core/.gitignore
new file mode 100644
index 00000000..8f0ac9b9
--- /dev/null
+++ b/auth/auth-core/.gitignore
@@ -0,0 +1,5 @@
+/.settings
+/bin
+/target
+/.classpath
+/.project
diff --git a/auth/auth-core/pom.xml b/auth/auth-core/pom.xml
new file mode 100644
index 00000000..a8002024
--- /dev/null
+++ b/auth/auth-core/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2017 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+-->
+<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.auth</groupId>
+ <artifactId>parent</artifactId>
+ <version>2.1.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>aaf-auth-core</artifactId>
+ <name>AAF Auth Core</name>
+ <description>Core Library for AAF Auth Components</description>
+ <packaging>jar</packaging>
+
+ <developers>
+ <developer>
+ <name>Jonathan Gathman</name>
+ <email>jonathan.gathman@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Architect</role>
+ <role>Lead Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Gabe Maurer</name>
+ <email>gabe.maurer@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ <developer>
+ <name>Ian Howell</name>
+ <email>ian.howell@att.com</email>
+ <organization>ATT</organization>
+ <roles>
+ <role>Developer</role>
+ </roles>
+ </developer>
+ </developers>
+
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>aaf-misc-env</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>aaf-cadi-aaf</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.misc</groupId>
+ <artifactId>aaf-misc-log4j</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onap.aaf.cadi</groupId>
+ <artifactId>aaf-cadi-core</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-servlet</artifactId>
+ <scope>compile</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-jmx</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ </dependencies>
+</project>
+
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/cache/Cache.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/cache/Cache.java
new file mode 100644
index 00000000..17368031
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/cache/Cache.java
@@ -0,0 +1,200 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.misc.env.Env;
+import org.onap.aaf.misc.env.Trans;
+
+/**
+ * Create and maintain a Map of Maps used for Caching
+ *
+ * @author Jonathan
+ *
+ * @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
+ *
+ * @author Jonathan
+ *
+ */
+ public final static class Dated {
+ public Date timestamp;
+ public List<?> data;
+ private long expireIn;
+
+ public Dated(List<?> data, long expireIn) {
+ timestamp = new Date(System.currentTimeMillis()+expireIn);
+ this.data = data;
+ this.expireIn = expireIn;
+ }
+
+ public <T> Dated(T t, long expireIn) {
+ timestamp = new Date(System.currentTimeMillis()+expireIn);
+ ArrayList<T> al = new ArrayList<T>(1);
+ al.add(t);
+ data = al;
+ this.expireIn = expireIn;
+ }
+
+ public void touch() {
+ timestamp = new Date(System.currentTimeMillis()+expireIn);
+ }
+ }
+
+ 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.
+ *
+ * @author Jonathan
+ *
+ */
+ 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/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java
new file mode 100644
index 00000000..6f0ea084
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/common/Define.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.common;
+
+import java.util.Map.Entry;
+
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.config.Config;
+
+public class Define {
+ private static String ROOT_NS = null;
+ private static String ROOT_COMPANY = null;
+
+ private final static String MSG = ".set(Access access) must be called before use";
+ public static final CharSequence ROOT_NS_TAG = "AAF_NS"; // use for certain Replacements in Location
+ private static final String ROOT_NS_TAG_DOT = ROOT_NS_TAG +".";
+
+ public static String ROOT_NS() {
+ if(ROOT_NS==null) {
+ throw new RuntimeException(Define.class.getName() + MSG);
+ }
+ return ROOT_NS;
+ }
+
+ public static String ROOT_COMPANY() {
+ if(ROOT_NS==null) {
+ throw new RuntimeException(Define.class.getName() + MSG);
+ }
+ return ROOT_COMPANY;
+ }
+
+ public static void set(Access access) throws CadiException {
+ ROOT_NS = access.getProperty(Config.AAF_ROOT_NS,"org.onap.aaf");
+ ROOT_COMPANY = access.getProperty(Config.AAF_ROOT_COMPANY,null);
+ 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.");
+ }
+ }
+
+ for( Entry<Object, Object> es : access.getProperties().entrySet()) {
+ if(es.getKey().toString().startsWith(ROOT_NS_TAG_DOT)) {
+ access.getProperties().setProperty(es.getKey().toString(),varReplace(es.getValue().toString()));
+ }
+ }
+
+ access.printf(Level.INIT,"AAF Root NS is %s, and AAF Company Root is %s",ROOT_NS,ROOT_COMPANY);
+ }
+
+ public static String varReplace(final String potential) {
+ if(potential.startsWith(ROOT_NS_TAG_DOT)) {
+ return ROOT_NS + potential.substring(6);
+ } else {
+ return potential;
+ }
+ }
+
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzEnv.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzEnv.java
new file mode 100644
index 00000000..0bbe079e
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzEnv.java
@@ -0,0 +1,310 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Symm;
+import org.onap.aaf.cadi.PropAccess.LogIt;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Decryptor;
+import org.onap.aaf.misc.env.Encryptor;
+import org.onap.aaf.misc.env.impl.Log4JLogTarget;
+import org.onap.aaf.misc.env.log4j.LogFileNamer;
+import org.onap.aaf.misc.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
+ *
+ * @author Jonathan
+ *
+ */
+public class AuthzEnv extends RosettaEnv implements Access {
+ private long[] times = new long[20];
+ private int idx = 0;
+ private PropAccess access;
+
+ public AuthzEnv() {
+ super();
+ _init(new PropAccess());
+ }
+
+ public AuthzEnv(String ... args) {
+ super();
+ _init(new PropAccess(args));
+ }
+
+ public AuthzEnv(Properties props) {
+ super();
+ _init(new PropAccess(props));
+ }
+
+
+ public AuthzEnv(PropAccess pa) {
+ super();
+ _init(pa);
+ }
+
+ private final void _init(PropAccess pa) {
+ access = pa;
+ times = new long[20];
+ idx = 0;
+ }
+
+ private class Log4JLogit implements LogIt {
+
+ @Override
+ public void push(Level level, Object... elements) {
+ switch(level) {
+ case AUDIT:
+ audit.log(elements);
+ break;
+ case DEBUG:
+ debug.log(elements);
+ break;
+ case ERROR:
+ error.log(elements);
+ break;
+ case INFO:
+ info.log(elements);
+ break;
+ case INIT:
+ init.log(elements);
+ break;
+ case NONE:
+ break;
+ case WARN:
+ warn.log(elements);
+ break;
+ }
+
+ }
+
+ }
+
+ @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 {
+ access.load(is);
+ }
+
+ @Override
+ public void log(Level lvl, Object... msgs) {
+ access.log(lvl, msgs);
+ }
+
+ @Override
+ public void log(Exception e, Object... msgs) {
+ access.log(e,msgs);
+ }
+
+ @Override
+ public void printf(Level level, String fmt, Object... elements) {
+ access.printf(level, fmt, elements);
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.Access#willLog(org.onap.aaf.cadi.Access.Level)
+ */
+ @Override
+ public boolean willLog(Level level) {
+ return access.willLog(level);
+ }
+
+ @Override
+ public void setLogLevel(Level level) {
+ access.setLogLevel(level);
+ }
+
+ 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);
+
+ access.set(new Log4JLogit());
+ }
+
+ 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;
+ try {
+ s = Symm.obtain(this);
+ } catch (CadiException e1) {
+ throw new IOException(e1);
+ }
+ 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;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.env.impl.BasicEnv#getProperty(java.lang.String)
+ */
+ @Override
+ public String getProperty(String key) {
+ return access.getProperty(key);
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.env.impl.BasicEnv#getProperties(java.lang.String[])
+ */
+ @Override
+ public Properties getProperties(String... filter) {
+ return access.getProperties();
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.env.impl.BasicEnv#getProperty(java.lang.String, java.lang.String)
+ */
+ @Override
+ public String getProperty(String key, String defaultValue) {
+ return access.getProperty(key, defaultValue);
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.misc.env.impl.BasicEnv#setProperty(java.lang.String, java.lang.String)
+ */
+ @Override
+ public String setProperty(String key, String value) {
+ access.setProperty(key, value);
+ return value;
+ }
+
+ public PropAccess access() {
+ return access;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.cadi.Access#getProperties()
+ */
+ @Override
+ public Properties getProperties() {
+ return access.getProperties();
+ };
+
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java
new file mode 100644
index 00000000..a38a3e20
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTrans.java
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.TransStore;
+
+public interface AuthzTrans extends TransStore {
+ public enum REQD_TYPE {future(1),force(2),move(4),ns(8);
+ public final int bit;
+
+ REQD_TYPE(int bit) {
+ this.bit = bit;
+ }
+ };
+
+ public abstract AuthzTrans set(HttpServletRequest req);
+
+ public abstract String user();
+
+ public abstract void setUser(TaggedPrincipal p);
+
+ public abstract TaggedPrincipal 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 Organization org();
+
+ public abstract boolean requested(REQD_TYPE requested);
+
+ public void requested(REQD_TYPE requested, boolean b);
+
+ public abstract void logAuditTrail(LogTarget lt);
+
+ public abstract Date now();
+
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java
new file mode 100644
index 00000000..a25c5f31
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransFilter.java
@@ -0,0 +1,181 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import java.security.Principal;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.auth.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.TaggedPrincipal;
+import org.onap.aaf.cadi.principal.TrustPrincipal;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans.Metric;
+
+public class AuthzTransFilter extends TransFilter<AuthzTrans> {
+ private AuthzEnv env;
+ public Metric serviceMetric;
+ public static Slot transIDslot,specialLogSlot;
+
+ public static final String TRANS_ID_SLOT = "TRANS_ID_SLOT";
+ public static final String SPECIAL_LOG_SLOT = "SPECIAL_LOG_SLOT";
+
+ public static final int BUCKETSIZE = 2;
+
+ public AuthzTransFilter(AuthzEnv env, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException {
+ super(env.access(),con, tc, additionalTafLurs);
+ this.env = env;
+ serviceMetric = new Metric();
+ serviceMetric.buckets = new float[BUCKETSIZE];
+ if(transIDslot==null) {
+ transIDslot = env.slot(TRANS_ID_SLOT);
+ }
+ if(specialLogSlot==null) {
+ specialLogSlot = env.slot(SPECIAL_LOG_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((TaggedPrincipal)p); // We only work with TaggedPrincipals in Authz
+ }
+
+ @Override
+ protected void tallyHo(AuthzTrans trans) {
+ Boolean b = trans.get(specialLogSlot, false);
+ LogTarget lt = b?trans.warn():trans.info();
+
+ if(lt.isLoggable()) {
+ // Transaction is done, now post full Audit Trail
+ 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(lt,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];
+ }
+
+ Long tsi;
+ if((tsi=trans.get(transIDslot, null))!=null) {
+ sb.append(" TraceID=");
+ sb.append(Long.toHexString(tsi));
+ sb.append('\n');
+ }
+ // 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]);
+ lt.log(sb);
+ } else {
+ // Single Line entry
+ // IMPORTANT!!! if you add more entries here, change "BUCKETSIZE"!!!
+ StringBuilder content = new StringBuilder();
+ Metric m = trans.auditTrail(lt,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).personalName()); // UserChain
+ sb.append(')');
+ } else {
+ sb.append('[');
+ if(p instanceof TaggedPrincipal) {
+ sb.append(((TaggedPrincipal)p).tag());
+ } else {
+ sb.append(p.getClass().getSimpleName());
+ }
+ sb.append(']');
+ }
+ }
+ sb.append(",ip=");
+ sb.append(trans.ip());
+ sb.append(",port=");
+ sb.append(trans.port());
+// Current code won't ever get here... Always does a Full Audit Trail
+// Long tsi;
+// if((tsi=trans.get(transIDslot, null))!=null) {
+// sb.append(",TraceID=");
+// sb.append(Long.toHexString(tsi));
+// }
+ sb.append(",ms=");
+ sb.append(m.total);
+ sb.append(",meth=");
+ sb.append(trans.meth());
+ sb.append(",path=");
+ sb.append(trans.path());
+
+ if(content.length()>0) {
+ sb.append(",msg=\"");
+ int start = content.lastIndexOf(",msg=\"");
+ if(start>=0) {
+ sb.append(content,start+6,content.length()-1);
+ } else {
+ sb.append(content);
+ }
+ sb.append('"');
+ }
+
+ trans.warn().log(sb);
+ }
+ }
+
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java
new file mode 100644
index 00000000..2ca8dfd7
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransImpl.java
@@ -0,0 +1,216 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.impl.BasicTrans;
+
+public class AuthzTransImpl extends BasicTrans implements AuthzTrans {
+ private TaggedPrincipal user;
+ private String ip,agent,meth,path;
+ private int port;
+ private Lur lur;
+ private Organization org;
+ private int mask;
+ private Date now;
+ public AuthzTransImpl(AuthzEnv env) {
+ super(env);
+ ip="n/a";
+ org=null;
+ mask=0;
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#set(javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public AuthzTrans set(HttpServletRequest req) {
+ user = (TaggedPrincipal)req.getUserPrincipal();
+ ip = req.getRemoteAddr();
+ port = req.getRemotePort();
+ agent = req.getHeader("User-Agent");
+ meth = req.getMethod();
+ path = req.getPathInfo();
+
+ for(REQD_TYPE rt : REQD_TYPE.values()) {
+ requested(rt,req);
+ }
+ // Handle alternate "request" for "future"
+ String request = req.getParameter("request");
+ if(request!=null) {
+ requested(REQD_TYPE.future,(request.length()==0 || "true".equalsIgnoreCase(request)));
+ }
+
+ org=null;
+ return this;
+ }
+
+ @Override
+ public void setUser(TaggedPrincipal p) {
+ user = p;
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#user()
+ */
+ @Override
+ public String user() {
+ return user==null?"n/a":user.getName();
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#getUserPrincipal()
+ */
+ @Override
+ public TaggedPrincipal getUserPrincipal() {
+ return user;
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#ip()
+ */
+ @Override
+ public String ip() {
+ return ip;
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#port()
+ */
+ @Override
+ public int port() {
+ return port;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.env.test.AuthzTrans#meth()
+ */
+ @Override
+ public String meth() {
+ return meth;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.env.test.AuthzTrans#path()
+ */
+ @Override
+ public String path() {
+ return path;
+ }
+
+ /**
+ * @see org.onap.aaf.auth.env.test.AuthTrans#agent()
+ */
+ @Override
+ public String agent() {
+ return agent;
+ }
+
+ @Override
+ public AuthzEnv env() {
+ return (AuthzEnv)delegate;
+ }
+
+ @Override
+ public boolean requested(REQD_TYPE requested) {
+ return (mask&requested.bit)==requested.bit;
+ }
+
+ public void requested(REQD_TYPE requested, boolean b) {
+ if(b) {
+ mask|=requested.bit;
+ } else {
+ mask&=~requested.bit;
+ }
+ }
+
+ private void requested(REQD_TYPE reqtype, HttpServletRequest req) {
+ String p = req.getParameter(reqtype.name());
+ if(p!=null) {
+ requested(reqtype,p.length()==0 || "true".equalsIgnoreCase(p));
+ }
+ }
+
+ @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.auth.env.test.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.auth.env.test.AuthzTrans#logAuditTrailOnly(com.att.inno.env.LogTarget)
+ */
+ @Override
+ public void logAuditTrail(LogTarget lt) {
+ if(lt.isLoggable()) {
+ StringBuilder sb = new StringBuilder();
+ auditTrail(1, sb);
+ lt.log(sb);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.env.test.AuthzTrans#now()
+ */
+ @Override
+ public Date now() {
+ if(now==null) {
+ now = new Date();
+ }
+ return now;
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransOnlyFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransOnlyFilter.java
new file mode 100644
index 00000000..2488cc7e
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/AuthzTransOnlyFilter.java
@@ -0,0 +1,86 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.auth.rserv.TransOnlyFilter;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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, TaggedPrincipal 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/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java
new file mode 100644
index 00000000..13f6551b
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/env/NullTrans.java
@@ -0,0 +1,234 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.env;
+
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.Decryptor;
+import org.onap.aaf.misc.env.Encryptor;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.StaticSlot;
+import org.onap.aaf.misc.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;
+ }
+
+ private Date now;
+
+ public void checkpoint(String text) {}
+ public void checkpoint(String text, int additionalFlag) {}
+ public Metric auditTrail(int indent, StringBuilder sb, int... flag) {return null;}
+
+ @Override
+ public Metric auditTrail(LogTarget lt, 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 TaggedPrincipal getUserPrincipal() {
+ return null;
+ }
+
+ @Override
+ public void setUser(TaggedPrincipal p) {
+ }
+
+ @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 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 Organization org() {
+ return Organization.NULL;
+ }
+
+ @Override
+ public void logAuditTrail(LogTarget lt) {
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.env.test.AuthzTrans#requested(org.onap.aaf.auth.env.test.AuthzTrans.REQD_TYPE)
+ */
+ @Override
+ public boolean requested(REQD_TYPE requested) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.onap.aaf.auth.env.test.AuthzTrans#requested(org.onap.aaf.auth.env.test.AuthzTrans.REQD_TYPE, boolean)
+ */
+ @Override
+ public void requested(REQD_TYPE requested, boolean b) {
+ }
+
+ @Override
+ public Date now() {
+ if(now==null) {
+ now = new Date();
+ }
+ return now;
+ }
+}
+
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/DirectIntrospectImpl.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/DirectIntrospectImpl.java
new file mode 100644
index 00000000..41f0e74a
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/DirectIntrospectImpl.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.layer;
+
+public class DirectIntrospectImpl {
+
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/FacadeImpl.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/FacadeImpl.java
new file mode 100644
index 00000000..81fc1e26
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/FacadeImpl.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.layer;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.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");
+ }
+
+ protected void setCacheControlOff(HttpServletResponse response) {
+ response.setHeader("Cache-Control", "no-store");
+ response.setHeader("Pragma", "no-cache");
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/Result.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/Result.java
new file mode 100644
index 00000000..e61cf2e8
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/layer/Result.java
@@ -0,0 +1,328 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.
+ *
+ * @author Jonathan
+ *
+ */
+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
+ *
+ * @author Jonathan
+ *
+ */
+
+ /**
+ * 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}");
+ }
+ if(value!=null) {
+ 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/auth/auth-core/src/main/java/org/onap/aaf/auth/local/AbsData.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/AbsData.java
new file mode 100644
index 00000000..40e0b22c
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/AbsData.java
@@ -0,0 +1,206 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.auth.env.AuthzTrans;
+import org.onap.aaf.auth.local.DataFile.Token;
+import org.onap.aaf.auth.local.DataFile.Token.Field;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.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('.');
+ 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.getAbsolutePath(),"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 {
+ public Token tokenData;
+ private Field fieldData;
+
+ private Reuse(int size,char delim) {
+ tokenData = data.new Token(size);
+ fieldData = tokenData.new Field(delim);
+ }
+
+ public void reset() {
+ getFieldData().reset();
+ }
+
+ public void pos(int rec) {
+ getFieldData().reset();
+ tokenData.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 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.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/local/DataFile.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/DataFile.java
new file mode 100644
index 00000000..bb9fb1fd
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/DataFile.java
@@ -0,0 +1,190 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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 boolean isOpened() {
+ return mapBuff!=null;
+ }
+ public void close() throws IOException {
+ if(channel!=null){
+ channel.close();
+ }
+ if(rafile!=null) {
+ rafile.close();
+ }
+ mapBuff = null;
+ }
+
+ public long size() throws IOException {
+ return channel==null?0: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/auth/auth-core/src/main/java/org/onap/aaf/auth/local/TextIndex.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/TextIndex.java
new file mode 100644
index 00000000..5169cf88
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/local/TextIndex.java
@@ -0,0 +1,256 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.auth.local.DataFile.Token;
+import org.onap.aaf.auth.local.DataFile.Token.Field;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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();
+ dataFile=null;
+ }
+ }
+
+ public int find(Object key, AbsData.Reuse reuse, int offset) throws IOException {
+ return find(key,reuse.tokenData,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/auth/auth-core/src/main/java/org/onap/aaf/auth/org/EmailWarnings.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/EmailWarnings.java
new file mode 100644
index 00000000..8360ffcb
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/EmailWarnings.java
@@ -0,0 +1,33 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Executor.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Executor.java
new file mode 100644
index 00000000..a839ae73
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Executor.java
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
new file mode 100644
index 00000000..6d7a3586
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/Organization.java
@@ -0,0 +1,515 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.auth.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.
+ *
+ * @author Jonathan
+ *
+ */
+public interface Organization {
+ public static final String N_A = "n/a";
+
+ public interface Identity {
+ public String id();
+ public String fullID() throws OrganizationException; // Fully Qualified ID (includes Domain of Organization)
+ public String type(); // Must be one of "IdentityTypes", see below
+ public Identity responsibleTo() throws OrganizationException; // Chain of Command, or Application ID Sponsor
+ public List<String> delegate(); // Someone who has authority to act on behalf of Identity
+ public String email();
+ public String fullName();
+ public String firstName();
+ /**
+ * If Responsible entity, then String returned is "null" meaning "no Objection".
+ * If String exists, it is the Policy objection text setup by the entity.
+ * @return
+ */
+ public String mayOwn(); // Is id passed belong to a person suitable to be Responsible for content Management
+ public boolean isFound(); // Is Identity found in Identity stores
+ public boolean isPerson(); // Whether a Person or a Machine (App)
+ 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(AuthzTrans trans, 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(final AuthzTrans trans, final String id, final String password, final String ... prev);
+
+ /**
+ * Return a list of Strings denoting Organization Password Rules, suitable for posting on a WebPage with <p>
+ */
+ public String[] getPasswordRules();
+
+ /**
+ *
+ * @param id
+ * @return
+ */
+ public boolean isValidCred(final AuthzTrans trans, final 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;
+
+ /**
+ * 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_RESPONSIBLE,
+ MAY_EXTEND_CRED_EXPIRES,
+ MAY_APPLY_DEFAULT_REALM
+ }
+
+ /**
+ * 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 User 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);
+
+ 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 String[] nullStringArray = new String[0];
+ private final Identity nullIdentity = new Identity() {
+ List<String> nullUser = new ArrayList<String>();
+ @Override
+ public String type() {
+ return N_A;
+ }
+
+ @Override
+ public String mayOwn() {
+ return N_A; // negative case
+ }
+
+ @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 nullUser;
+ }
+ @Override
+ public String fullName() {
+ return N_A;
+ }
+ @Override
+ public Organization org() {
+ return NULL;
+ }
+ @Override
+ public String firstName() {
+ return N_A;
+ }
+ @Override
+ public boolean isPerson() {
+ return false;
+ }
+
+ @Override
+ public Identity responsibleTo() {
+ 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(final AuthzTrans trans, String id) {
+ return N_A;
+ }
+
+ @Override
+ public String isValidPassword(final AuthzTrans trans, final String user, final String password, final 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;
+ }
+
+ @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(final AuthzTrans trans, final 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
+ }
+
+ };
+ }
+
+ @Override
+ public String[] getPasswordRules() {
+ return nullStringArray;
+ }
+
+ };
+
+}
+
+
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationException.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationException.java
new file mode 100644
index 00000000..ed1d398b
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationException.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationFactory.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationFactory.java
new file mode 100644
index 00000000..36efb5dc
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/org/OrganizationFactory.java
@@ -0,0 +1,125 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.org;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.cadi.util.FQI;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.impl.BasicEnv;
+
+/**
+ * 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.auth.org.test.att.ATT
+ *
+ * @author Pavani, Jonathan
+ *
+ */
+public class OrganizationFactory {
+ private static final String ORGANIZATION_DOT = "Organization.";
+ private static Organization defaultOrg = null;
+ private static Map<String,Organization> orgs = new ConcurrentHashMap<String,Organization>();
+ public static Organization init(BasicEnv env) throws OrganizationException {
+ int idx = ORGANIZATION_DOT.length();
+ Organization org,firstOrg = null;
+
+ for(Entry<Object, Object> es : env.getProperties().entrySet()) {
+ String key = es.getKey().toString();
+ if(key.startsWith(ORGANIZATION_DOT)) {
+ org = obtain(env,key.substring(idx));
+ if(firstOrg==null) {
+ firstOrg = org;
+ }
+ }
+ }
+ if(defaultOrg == null) {
+ defaultOrg = firstOrg;
+ }
+ return defaultOrg;
+ }
+ public static Organization obtain(Env env,final String theNS) throws OrganizationException {
+ String orgNS;
+ if(theNS.indexOf('@')>=0) {
+ orgNS=FQI.reverseDomain(theNS);
+ } else {
+ orgNS=theNS;
+ }
+ Organization org = orgs.get(orgNS);
+ if(org == null) {
+ String orgClass = env.getProperty(ORGANIZATION_DOT+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(Env.class,String.class);
+ org = cnst.newInstance(env,orgNS);
+ } catch (ClassNotFoundException | NoSuchMethodException | SecurityException |
+ InstantiationException | IllegalAccessException | IllegalArgumentException |
+ InvocationTargetException e) {
+ env.error().log(e, "Error on Organization Construction");
+ throw new OrganizationException(e);
+ }
+ }
+ orgs.put(orgNS, org);
+ if("true".equalsIgnoreCase(env.getProperty(orgNS+".default"))) {
+ defaultOrg = org;
+ }
+
+ }
+ if(org==null) {
+ if(defaultOrg!=null) {
+ org=defaultOrg;
+ orgs.put(orgNS, org);
+ }
+ }
+ }
+
+ return org;
+ }
+
+ public static Organization get(AuthzTrans trans) throws OrganizationException {
+ String domain = FQI.reverseDomain(trans.user());
+ Organization org = orgs.get(domain);
+ if(org==null) {
+ org = defaultOrg; // can be null, btw, unless set.
+ }
+ return org;
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Acceptor.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Acceptor.java
new file mode 100644
index 00000000..1953694b
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Acceptor.java
@@ -0,0 +1,169 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.onap.aaf.misc.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
+ * @author Jonathan
+ *
+ * @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
+ }
+
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java
new file mode 100644
index 00000000..7bb276a2
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CachingFileAccess.java
@@ -0,0 +1,564 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+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 java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Store;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+/*
+ * CachingFileAccess
+ *
+ * Author: Jonathan Gathman, Gathsys 2010
+ *
+ */
+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_PATH.equals(args[i])) {
+ store.put(store.staticSlot(CFA_WEB_PATH), 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;
+ public final static String CFA_WEB_PATH = "aaf_cfa_web_path";
+ // 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 = "aaf_cfa_cache_check_interval";
+ private final static String CFA_MAX_SIZE = "aaf_cfa_max_size"; // Cache size limit
+ private final static String CFA_CLEAR_COMMAND = "aaf_cfa_clear_command";
+
+ // 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) throws IOException {
+ 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");
+ typeMap.put("props", "text/plain");
+ typeMap.put("jks", "application/octet-stream");
+
+ timer = new Timer("Caching Cleanup",true);
+ timer.schedule(new Cleanup(content,500),60000,60000);
+
+ // Property params
+ web_path = env.get(env.staticSlot(CFA_WEB_PATH));
+ env.init().log("CachingFileAccess path: " + new File(web_path).getCanonicalPath());
+ 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");
+ String cmd = pathParam(req,":cmd");
+ System.out.print(key + clear_command);
+ if(key.equals(clear_command)) {
+ resp.setHeader("Content-Type",typeMap.get("txt"));
+ if("clear".equals(cmd)) {
+ content.clear();
+ resp.setStatus(200/*HttpStatus.OK_200*/);
+ } else {
+ resp.setStatus(400/*HttpStatus.BAD_REQUEST_400 */);
+ }
+ return;
+ }
+ Content c = load(logT , web_path,cmd!=null && cmd.length()>0?key+'/'+cmd:key, null, checkInterval);
+ if(c.attachmentOnly) {
+ resp.setHeader("Content-disposition", "attachment");
+ }
+ c.setHeader(resp);
+ c.write(resp.getOutputStream());
+ 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 = new Timer();
+ 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
+ }
+ boolean isRoot;
+ String fileName;
+ if("-".equals(key)) {
+ fileName = dataRoot;
+ isRoot = true;
+ } else {
+ fileName=dataRoot + '/' + key;
+ isRoot = false;
+ }
+ 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.isDirectory()) {
+ cacheMe = false;
+ c = new DirectoryContent(f,isRoot);
+ } else {
+ 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(404/*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(200/*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 DirectoryContent extends Content {
+ private static final Pattern A_NUMBER = Pattern.compile("\\d");
+ private static final String H1 = "<html><head><title>AAF Fileserver</title></head><body><h1>AAF Fileserver</h1><h2>";
+ private static final String H2 = "</h2><ul>\n";
+ private static final String F = "\n</ul></body></html>";
+ private File[] files;
+ private String name;
+ private boolean notRoot;
+
+ public DirectoryContent(File directory, boolean isRoot) {
+ notRoot = !isRoot;
+
+ files = directory.listFiles();
+ Arrays.sort(files,new Comparator<File>() {
+ @Override
+ public int compare(File f1, File f2) {
+ // See if there are Numbers in the name
+ Matcher m1 = A_NUMBER.matcher(f1.getName());
+ Matcher m2 = A_NUMBER.matcher(f2.getName());
+ if(m1.find() && m2.find()) {
+ // if numbers, are the numbers in the same start position
+ int i1 = m1.start();
+ int i2 = m2.start();
+
+ // If same start position and the text is the same, then reverse sort
+ if(i1==i2 && f1.getName().startsWith(f2.getName().substring(0,i1))) {
+ // reverse sort files that start similarly, but have numbers in them
+ return f2.compareTo(f1);
+ }
+ }
+ return f1.compareTo(f2);
+ }
+
+ });
+ name = directory.getName();
+ attachmentOnly = false;
+ contentType = "text/html";
+ }
+
+
+ @Override
+ public void write(Writer w) throws IOException {
+ w.append(H1);
+ w.append(name);
+ w.append(H2);
+ for (File f : files) {
+ w.append("<li><a href=\"");
+ if(notRoot) {
+ w.append(name);
+ w.append('/');
+ }
+ w.append(f.getName());
+ w.append("\">");
+ w.append(f.getName());
+ w.append("</a></li>\n");
+ }
+ w.append(F);
+ w.flush();
+ }
+
+ @Override
+ public void write(OutputStream os) throws IOException {
+ write(new OutputStreamWriter(os));
+ }
+
+ }
+
+ 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.
+ * @author Jonathan
+ *
+ */
+ 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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CodeSetter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CodeSetter.java
new file mode 100644
index 00000000..6ea8880b
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/CodeSetter.java
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.aaf.misc.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;
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Content.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Content.java
new file mode 100644
index 00000000..ae329ce2
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Content.java
@@ -0,0 +1,115 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+import java.util.List;
+
+import org.onap.aaf.misc.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.
+ *
+ * @author Jonathan
+ *
+ */
+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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpCode.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpCode.java
new file mode 100644
index 00000000..0bfe310a
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpCode.java
@@ -0,0 +1,118 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.onap.aaf.misc.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/*
+ *
+ * @author Jonathan
+ *
+ * @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) {
+ String rv = match.param(req.getPathInfo(), key);
+ if(rv!=null) {
+ rv = rv.trim();
+ if(rv.endsWith("/")) {
+ rv = rv.substring(0, rv.length()-1);
+ }
+ }
+ return rv;
+ }
+
+ // 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;
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpMethods.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpMethods.java
new file mode 100644
index 00000000..4dbaf17b
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/HttpMethods.java
@@ -0,0 +1,29 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+public enum HttpMethods {
+ POST,
+ GET,
+ PUT,
+ DELETE
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Match.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Match.java
new file mode 100644
index 00000000..ac8b31c1
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Match.java
@@ -0,0 +1,211 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.
+ *
+ * @author Jonathan
+ *
+ */
+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();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Pair.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Pair.java
new file mode 100644
index 00000000..810f9129
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Pair.java
@@ -0,0 +1,44 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+/**
+ * A pair of generic Objects.
+ *
+ * @author Jonathan
+ *
+ * @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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java
new file mode 100644
index 00000000..4ae0f882
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RServlet.java
@@ -0,0 +1,154 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Route.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Route.java
new file mode 100644
index 00000000..9ae202a2
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Route.java
@@ -0,0 +1,141 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RouteReport.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RouteReport.java
new file mode 100644
index 00000000..5de2ebe3
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/RouteReport.java
@@ -0,0 +1,33 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Routes.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Routes.java
new file mode 100644
index 00000000..fefb8f3c
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Routes.java
@@ -0,0 +1,89 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.misc.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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java
new file mode 100644
index 00000000..1011767a
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransFilter.java
@@ -0,0 +1,156 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.config.Config;
+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.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.TransStore;
+import org.onap.aaf.misc.env.util.Split;
+
+/**
+ * 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.
+ *
+ * @author Jonathan
+ *
+ */
+public abstract class TransFilter<TRANS extends TransStore> implements Filter {
+ public static final String TRANS_TAG = "__TRANS__";
+
+ private CadiHTTPManip cadi;
+
+ private final String[] no_authn;
+
+ public TransFilter(Access access, Connector con, TrustChecker tc, Object ... additionalTafLurs) throws CadiException {
+ cadi = new CadiHTTPManip(access, con, tc, additionalTafLurs);
+ String no = access.getProperty(Config.CADI_NOAUTHN, null);
+ if(no!=null) {
+ no_authn = Split.split(':', no);
+ } else {
+ no_authn=null;
+ }
+ }
+
+ @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;
+
+ if(no_authn!=null) {
+ for(String prefix : no_authn) {
+ if(req.getPathInfo().startsWith(prefix)) {
+ chain.doFilter(request, response);
+ return;
+ }
+ }
+ }
+
+ TimeTaken security = trans.start("CADI Security", Env.SUB);
+ TafResp resp;
+ RESP r;
+ CadiWrap cw = null;
+ try {
+ resp = cadi.validate(req,res,trans);
+ 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());
+ if(cadi.notCadi(cw, res)) {
+ 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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransOnlyFilter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransOnlyFilter.java
new file mode 100644
index 00000000..e0f7512d
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TransOnlyFilter.java
@@ -0,0 +1,77 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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.
+ *
+ * @author Jonathan
+ *
+ */
+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, TaggedPrincipal 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/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TypedCode.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TypedCode.java
new file mode 100644
index 00000000..82b291c7
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/TypedCode.java
@@ -0,0 +1,269 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.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.
+ *
+ * @author Jonathan
+ *
+ * @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;
+ }
+
+ } \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Version.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Version.java
new file mode 100644
index 00000000..ce0981fe
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/Version.java
@@ -0,0 +1,93 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv;
+
+
+/**
+ * Analyze and hold Version information for Code
+ *
+ * @author Jonathan
+ *
+ */
+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();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/doc/ApiDoc.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/doc/ApiDoc.java
new file mode 100644
index 00000000..e2914752
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/rserv/doc/ApiDoc.java
@@ -0,0 +1,40 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.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.auth.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/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsService.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsService.java
new file mode 100644
index 00000000..e1c01718
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsService.java
@@ -0,0 +1,156 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.server;
+
+import java.security.NoSuchAlgorithmException;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.servlet.Filter;
+
+import org.onap.aaf.auth.common.Define;
+import org.onap.aaf.auth.rserv.RServlet;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
+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.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.cadi.register.Registrant;
+import org.onap.aaf.cadi.util.Split;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.impl.BasicEnv;
+
+public abstract class AbsService<ENV extends BasicEnv, TRANS extends Trans> extends RServlet<TRANS> {
+ public final Access access;
+ public final ENV env;
+ private AAFConHttp aafCon;
+
+ public final String app_name;
+ public final String app_version;
+ public final String app_interface_version;
+ public final String ROOT_NS;
+
+ public AbsService(final Access access, final ENV env) throws CadiException {
+ Define.set(access);
+ ROOT_NS = Define.ROOT_NS();
+ this.access = access;
+ this.env = env;
+
+ String component = access.getProperty(Config.AAF_COMPONENT, null);
+ final String[] locator_deploy;
+
+ if(component == null) {
+ locator_deploy = null;
+ } else {
+ locator_deploy = Split.splitTrim(':', component);
+ }
+
+ if(component == null || locator_deploy==null || locator_deploy.length<2) {
+ throw new CadiException("AAF Component must include the " + Config.AAF_COMPONENT + " property, <fully qualified service name>:<full deployed version (i.e. 2.1.3.13)");
+ }
+ final String[] version = Split.splitTrim('.', locator_deploy[1]);
+ if(version==null || version.length<2) {
+ throw new CadiException("AAF Component Version must have at least Major.Minor version");
+ }
+ app_name = Define.varReplace(locator_deploy[0]);
+ app_version = locator_deploy[1];
+ app_interface_version = version[0]+'.'+version[1];
+
+ // Print Cipher Suites Available
+ if(access.willLog(Level.DEBUG)) {
+ SSLContext context;
+ try {
+ context = SSLContext.getDefault();
+ } catch (NoSuchAlgorithmException e) {
+ throw new CadiException("SSLContext issue",e);
+ }
+ 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');}
+ }
+ access.log(Level.DEBUG,sb);
+ }
+ }
+
+ public abstract Filter[] filters() throws CadiException, LocatorException;
+
+
+ public abstract Registrant<ENV>[] registrants(final int port) throws CadiException, LocatorException;
+
+ // Lazy Instantiation
+ public synchronized AAFConHttp aafCon() throws CadiException, LocatorException {
+ if(aafCon==null) {
+ if(access.getProperty(Config.AAF_URL,null)!=null) {
+ aafCon = _newAAFConHttp();
+ } else {
+ throw new CadiException("AAFCon cannot be constructed without " + Config.AAF_URL);
+ }
+ }
+ return aafCon;
+ }
+
+ /**
+ * Allow to be over ridden for special cases
+ * @return
+ * @throws LocatorException
+ */
+ protected synchronized AAFConHttp _newAAFConHttp() throws CadiException, LocatorException {
+ try {
+ if(aafCon==null) {
+ aafCon = new AAFConHttp(access);
+ }
+ return aafCon;
+ } catch (APIException e) {
+ throw new CadiException(e);
+ }
+ }
+
+ // This is a method, so we can overload for AAFAPI
+ public String aaf_url() {
+ return access.getProperty(Config.AAF_URL, null);
+ }
+
+ public Rcli<?> client() throws CadiException {
+ return aafCon.client(Config.AAF_DEFAULT_VERSION);
+ }
+
+ public Rcli<?> clientAsUser(TaggedPrincipal p) throws CadiException {
+ return aafCon.client(Config.AAF_DEFAULT_VERSION).forUser(
+ new HTransferSS(p,app_name, aafCon.securityInfo()));
+ }
+
+ public<RET> RET clientAsUser(TaggedPrincipal p,Retryable<RET> retryable) throws APIException, LocatorException, CadiException {
+ return aafCon.hman().best(new HTransferSS(p,app_name, aafCon.securityInfo()), retryable);
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java
new file mode 100644
index 00000000..1a6c54d7
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/AbsServiceStarter.java
@@ -0,0 +1,95 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.server;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.auth.rserv.RServlet;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.register.Registrant;
+import org.onap.aaf.cadi.register.Registrar;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+public abstract class AbsServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> implements ServiceStarter {
+ private Registrar<ENV> registrar;
+ private boolean do_register;
+ protected AbsService<ENV,TRANS> service;
+
+
+ public AbsServiceStarter(final AbsService<ENV,TRANS> service) {
+ this.service = service;
+ try {
+ OrganizationFactory.init(service.env);
+ } catch (OrganizationException e) {
+ service.access.log(e, "Missing defined Organzation Plugins");
+ System.exit(3);
+ }
+ // do_register - this is used for specialty Debug Situations. Developer can create an Instance for a remote system
+ // for Debugging purposes without fear that real clients will start to call your debug instance
+ do_register = !"TRUE".equalsIgnoreCase(access().getProperty("aaf_locate_no_register",null));
+ _propertyAdjustment();
+ }
+
+ public abstract void _start(RServlet<TRANS> rserv) throws Exception;
+ public abstract void _propertyAdjustment();
+
+ public ENV env() {
+ return service.env;
+ }
+
+ public Access access() {
+ return service.access;
+ }
+
+ @Override
+ public final void start() throws Exception {
+ _start(service);
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ shutdown();
+ }
+ });
+ }
+
+ @SafeVarargs
+ public final synchronized void register(final Registrant<ENV> ... registrants) {
+ if(do_register) {
+ if(registrar==null) {
+ registrar = new Registrar<ENV>(env(),false);
+ }
+ for(Registrant<ENV> r : registrants) {
+ registrar.register(r);
+ }
+ }
+ }
+
+ @Override
+ public void shutdown() {
+ if(registrar!=null) {
+ registrar.close(env());
+ registrar=null;
+ }
+ if(service!=null) {
+ service.destroy();
+ }
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java
new file mode 100644
index 00000000..dbf24cc6
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/JettyServiceStarter.java
@@ -0,0 +1,255 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.server;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Properties;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.http.HttpVersion;
+import org.eclipse.jetty.server.HttpConfiguration;
+import org.eclipse.jetty.server.HttpConnectionFactory;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.SecureRequestCustomizer;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.server.SslConnectionFactory;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.eclipse.jetty.util.ssl.SslContextFactory;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.rserv.RServlet;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.cadi.config.SecurityInfo;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.util.Split;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+
+public class JettyServiceStarter<ENV extends RosettaEnv, TRANS extends Trans> extends AbsServiceStarter<ENV,TRANS> {
+
+ private boolean secure;
+
+ public JettyServiceStarter(final AbsService<ENV,TRANS> service) throws OrganizationException {
+ super(service);
+ secure = true;
+ }
+
+ /**
+ * Specifically set this Service starter to Insecure (HTTP) Mode.
+ * @return
+ */
+ public JettyServiceStarter<ENV,TRANS> insecure() {
+ secure = false;
+ return this;
+ }
+
+// @Override
+// public void _propertyAdjustment() {
+// Properties props = access().getProperties();
+// Object temp = null;
+// // Critical - if no Security Protocols set, then set it. We'll just get messed up if not
+// if((temp=props.get(Config.CADI_PROTOCOLS))==null) {
+// if((temp=props.get(Config.HTTPS_PROTOCOLS))==null) {
+// props.put(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT);
+// } else {
+// props.put(Config.CADI_PROTOCOLS, temp);
+// }
+// }
+//
+// if("1.7".equals(System.getProperty("java.specification.version"))) {
+// System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
+// }
+// System.setProperty(Config.HTTPS_CIPHER_SUITES, temp.toString());
+// }
+
+ @Override
+ public void _propertyAdjustment() {
+// System.setProperty("com.sun.management.jmxremote.port", "8081");
+ Properties props = access().getProperties();
+ Object httpproto = null;
+ // Critical - if no Security Protocols set, then set it. We'll just get messed up if not
+ if((httpproto=props.get(Config.CADI_PROTOCOLS))==null) {
+ if((httpproto=props.get(Config.HTTPS_PROTOCOLS))==null) {
+ props.put(Config.CADI_PROTOCOLS, (httpproto=SecurityInfo.HTTPS_PROTOCOLS_DEFAULT));
+ } else {
+ props.put(Config.CADI_PROTOCOLS, httpproto);
+ }
+ }
+
+ if("1.7".equals(System.getProperty("java.specification.version")) && (httpproto==null || (httpproto instanceof String && ((String)httpproto).contains("TLSv1.2")))) {
+ System.setProperty(Config.HTTPS_CIPHER_SUITES, Config.HTTPS_CIPHER_SUITES_DEFAULT);
+ }
+ }
+
+ @Override
+ public void _start(RServlet<TRANS> rserv) throws Exception {
+ final String hostname = access().getProperty(Config.HOSTNAME, "localhost");
+ final int port = Integer.parseInt(access().getProperty("port","0"));
+ final String keystore = access().getProperty(Config.CADI_KEYSTORE, null);
+ final int IDLE_TIMEOUT = Integer.parseInt(access().getProperty(Config.AAF_CONN_IDLE_TIMEOUT, Config.AAF_CONN_IDLE_TIMEOUT_DEF));
+ Server server = new Server();
+
+ ServerConnector conn;
+ String protocol;
+ if(!secure || keystore==null) {
+ conn = new ServerConnector(server);
+ protocol = "http";
+ } else {
+ protocol = "https";
+
+ String keystorePassword = access().getProperty(Config.CADI_KEYSTORE_PASSWORD, null);
+ if(keystorePassword==null) {
+ throw new CadiException("No Keystore Password configured for " + keystore);
+ }
+ SslContextFactory sslContextFactory = new SslContextFactory();
+ sslContextFactory.setKeyStorePath(keystore);
+ String temp;
+ sslContextFactory.setKeyStorePassword(temp=access().decrypt(keystorePassword, true)); // don't allow unencrypted
+ sslContextFactory.setKeyManagerPassword(temp);
+ temp=null; // don't leave lying around
+
+ String truststore = access().getProperty(Config.CADI_TRUSTSTORE, null);
+ if(truststore!=null) {
+ String truststorePassword = access().getProperty(Config.CADI_TRUSTSTORE_PASSWORD, null);
+ if(truststorePassword==null) {
+ throw new CadiException("No Truststore Password configured for " + truststore);
+ }
+ sslContextFactory.setTrustStorePath(truststore);
+ sslContextFactory.setTrustStorePassword(access().decrypt(truststorePassword, true));
+ }
+ // Be able to accept only certain protocols, i.e. TLSv1.1+
+ final String[] protocols = Split.splitTrim(',', access().getProperty(Config.CADI_PROTOCOLS, SecurityInfo.HTTPS_PROTOCOLS_DEFAULT));
+ sslContextFactory.setIncludeProtocols(protocols);
+
+ // Want to use Client Certificates, if they exist.
+ sslContextFactory.setWantClientAuth(true);
+
+ // Optional future checks.
+ // sslContextFactory.setValidateCerts(true);
+ // sslContextFactory.setValidatePeerCerts(true);
+ // sslContextFactory.setEnableCRLDP(false);
+ // sslContextFactory.setEnableOCSP(false);
+ String certAlias = access().getProperty(Config.CADI_ALIAS, null);
+ if(certAlias!=null) {
+ sslContextFactory.setCertAlias(certAlias);
+ }
+
+ HttpConfiguration httpConfig = new HttpConfiguration();
+ httpConfig.setSecureScheme(protocol);
+ httpConfig.setSecurePort(port);
+ httpConfig.addCustomizer(new SecureRequestCustomizer());
+ // httpConfig.setOutputBufferSize(32768); Not sure why take this setting
+
+ conn = new ServerConnector(server,
+ new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
+ new HttpConnectionFactory(httpConfig)
+ );
+ }
+
+ // Setup JMX
+ // TODO trying to figure out how to set up/log ports
+// MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
+// MBeanContainer mbContainer=new MBeanContainer(mbeanServer);
+// server.addEventListener(mbContainer);
+// server.addBean(mbContainer);
+
+ // Add loggers MBean to server (will be picked up by MBeanContainer above)
+// server.addBean(Log.getLog());
+
+ conn.setHost(hostname);
+ conn.setPort(port);
+ conn.setIdleTimeout(IDLE_TIMEOUT);
+ server.addConnector(conn);
+
+ server.setHandler(new AbstractHandler() {
+ private FilterChain fc = buildFilterChain(service,new FilterChain() {
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
+ rserv.service(req, resp);
+ }
+ });
+
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest hreq, HttpServletResponse hresp) throws IOException, ServletException {
+ try {
+ fc.doFilter(hreq,hresp);
+ } catch (Exception e) {
+ service.access.log(e, "Error Processing " + target);
+ hresp.setStatus(500 /* Service Error */);
+ }
+ baseRequest.setHandled(true);
+ }
+ }
+ );
+
+ try {
+ access().printf(Level.INIT, "Starting service on %s:%d (%s)",hostname,port,InetAddress.getLocalHost().getHostAddress());
+ server.start();
+ access().log(Level.INIT,server.dump());
+ } catch (Exception e) {
+ access().log(e,"Error starting " + service.app_name);
+ System.exit(1);
+ }
+ try {
+ register(service.registrants(port));
+ access().printf(Level.INIT, "Starting Jetty Service for %s, version %s, on %s://%s:%d", service.app_name,service.app_version,protocol,hostname,port);
+ } catch(Exception e) {
+ access().log(e,"Error registering " + service.app_name);
+ // Question: Should Registered Services terminate?
+ }
+ server.join();
+ }
+
+ private FilterChain buildFilterChain(final AbsService<?,?> as, final FilterChain doLast) throws CadiException, LocatorException {
+ Filter[] filters = as.filters();
+ FilterChain fc = doLast;
+ for(int i=filters.length-1;i>=0;--i) {
+ fc = new FCImpl(filters[i],fc);
+ }
+ return fc;
+ }
+
+ private class FCImpl implements FilterChain {
+ private Filter f;
+ private FilterChain next;
+
+ public FCImpl(final Filter f, final FilterChain fc) {
+ this.f=f;
+ next = fc;
+
+ }
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse resp) throws IOException, ServletException {
+ f.doFilter(req,resp, next);
+ }
+ }
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/server/ServiceStarter.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/ServiceStarter.java
new file mode 100644
index 00000000..529d2d35
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/server/ServiceStarter.java
@@ -0,0 +1,26 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.server;
+
+public interface ServiceStarter {
+ public void start() throws Exception;
+ public void shutdown();
+}
diff --git a/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java b/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java
new file mode 100644
index 00000000..16c0d3ba
--- /dev/null
+++ b/auth/auth-core/src/main/java/org/onap/aaf/auth/validation/Validator.java
@@ -0,0 +1,204 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.validation;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.onap.aaf.auth.layer.Result;
+
+
+public class Validator {
+ private static final String ESSENTIAL = "\\x25\\x28\\x29\\x2C-\\x2E\\x30-\\x39\\x3D\\x40-\\x5A\\x5F\\x61-\\x7A";
+ private static final Pattern ESSENTIAL_CHARS = Pattern.compile("["+ESSENTIAL+"]+");
+ public static final Pattern ACTION_CHARS = Pattern.compile(
+ "["+ESSENTIAL+"]+" + // All AlphaNumeric+
+ "|\\*" // Just Star
+ );
+ public static final Pattern INST_CHARS = Pattern.compile(
+ "["+ESSENTIAL+"]+[\\*]*" + // All AlphaNumeric+ possibly ending with *
+ "|\\*" + // Just Star
+ "|(([:/]\\*)|([:/][!]{0,1}["+ESSENTIAL+"]+[\\*]*[:/]*))+" // Key :asdf:*:sdf*:sdk
+ );
+ public static final Pattern ID_CHARS = Pattern.compile("[\\w.-]+@[\\w.-]+");
+ public static final Pattern NAME_CHARS = Pattern.compile("[\\w.-]+");
+ public static final Pattern DESC_CHAR = Pattern.compile("["+ESSENTIAL+"\\x20]+");
+ public static List<String> nsKeywords;
+ protected final Pattern actionChars;
+ protected final Pattern instChars;
+ private StringBuilder msgs;
+
+ static {
+ nsKeywords = new ArrayList<String>();
+ nsKeywords.add(".access");
+ nsKeywords.add(".owner");
+ nsKeywords.add(".admin");
+ nsKeywords.add(".member");
+ nsKeywords.add(".perm");
+ nsKeywords.add(".role");
+ nsKeywords.add(".ns");
+ nsKeywords.add(".cred");
+ }
+
+ public Validator() {
+ actionChars = ACTION_CHARS;
+ instChars = INST_CHARS;
+ }
+
+ public final String errs() {
+ return msgs.toString();
+ }
+
+ public final Validator nullOrBlank(String name, String str) {
+ if(str==null) {
+ msg(name + " is null.");
+ } else if(str.length()==0) {
+ msg(name + " is blank.");
+ }
+ return this;
+ }
+
+ public final Validator isNull(String name, Object o) {
+ if(o==null) {
+ msg(name + " is null.");
+ }
+ return this;
+ }
+
+ protected final boolean noMatch(String str, Pattern p) {
+ return !p.matcher(str).matches();
+ }
+ protected final boolean nob(String str, Pattern p) {
+ return str==null || !p.matcher(str).matches();
+ }
+
+ protected final void msg(String ... strs) {
+ if(msgs==null) {
+ msgs=new StringBuilder();
+ }
+ for(String str : strs) {
+ msgs.append(str);
+ }
+ msgs.append('\n');
+ }
+
+ public final boolean err() {
+ return msgs!=null;
+ }
+
+ public final Validator notOK(Result<?> res) {
+ if(res==null) {
+ msgs.append("Result object is blank");
+ } else if(res.notOK()) {
+ msgs.append(res.getClass().getSimpleName() + " is not OK");
+ }
+ return this;
+ }
+
+ protected Validator intRange(String text, int target, int start, int end) {
+ if(target<start || target>end) {
+ msg(text + " is out of range (" + start + '-' + end + ')');
+ }
+ return this;
+ }
+
+ protected Validator floatRange(String text, float target, float start, float end) {
+ if(target<start || target>end) {
+ msg(text + " is out of range (" + start + '-' + end + ')');
+ }
+ return this;
+ }
+
+ protected Validator description(String type, String description) {
+ if(description!=null) {
+ if(noMatch(description, DESC_CHAR)) {
+ msg(type + " Description is invalid.");
+ }
+ }
+ return this;
+ }
+
+ public final Validator permType(String type) {
+ if(nob(type,NAME_CHARS)) {
+ msg("Perm Type [" +type + "] is invalid.");
+ }
+ return this;
+ }
+
+ public final Validator permType(String type, String ns) {
+ if(nob(type,NAME_CHARS)) {
+ msg("Perm Type [" + (ns==null?"":ns+(type.length()==0?"":'.'))+type + "] is invalid.");
+ }
+ return this;
+ }
+
+ public final Validator permInstance(String instance) {
+ if(nob(instance,instChars)) {
+ msg("Perm Instance [" + instance + "] is invalid.");
+ }
+ return this;
+ }
+
+ public final Validator permAction(String action) {
+ // TODO check for correct Splits? Type|Instance|Action ?
+ if(nob(action, actionChars)) {
+ msg("Perm Action [" + action + "] is invalid.");
+ }
+ return this;
+ }
+
+ public final Validator role(String role) {
+ if(nob(role, NAME_CHARS)) {
+ msg("Role [" + role + "] is invalid.");
+ }
+ return this;
+ }
+
+ public final Validator ns(String ns) {
+ if(nob(ns,NAME_CHARS)){
+ msg("NS [" + ns + "] is invalid.");
+ }
+ for(String s : nsKeywords) {
+ if(ns.endsWith(s)) {
+ msg("NS [" + ns + "] may not be named with NS keywords");
+ break;
+ }
+ }
+ return this;
+ }
+
+ public final Validator key(String key) {
+ if(nob(key,NAME_CHARS)) {
+ msg("NS Prop Key [" + key + "] is invalid");
+ }
+ return this;
+ }
+
+ public final Validator value(String value) {
+ if(nob(value,ESSENTIAL_CHARS)) {
+ msg("NS Prop value [" + value + "] is invalid");
+ }
+ return this;
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/common/test/JU_Define.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/common/test/JU_Define.java
new file mode 100644
index 00000000..89e1aa94
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/common/test/JU_Define.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.common.test;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.misc.env.Env;
+import static org.junit.Assert.*;
+
+//import com.att.authz.common.Define;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+//TODO: Gabe [JUnit] class path/ class Define is missing, com.att.authz.common also missing
+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);
+// }
+
+ @Test
+ public void netYetTested() {
+ fail("Tests not yet implemented");
+ }
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzEnv.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzEnv.java
new file mode 100644
index 00000000..1117fce7
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzEnv.java
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.env.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import org.onap.aaf.cadi.Access;
+import static org.mockito.Mockito.when;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.Access.Level;
+import org.onap.aaf.cadi.config.Config;
+import org.onap.aaf.misc.env.APIException;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import junit.framework.Assert;
+
+@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(){
+ PropAccess access = null;
+ Properties props = null;
+ authzEnv = new AuthzEnv();
+ AuthzEnv authzEnv1 = new AuthzEnv("Test");
+ AuthzEnv authzEnv2 = new AuthzEnv(props);
+ AuthzEnv authzEnv3 = new AuthzEnv(access);
+ }
+
+ @Test
+ public void testTransRate() {
+ Long Result = authzEnv.transRate();
+ System.out.println("value of result " +Result); //Expected 300000
+ assertNotNull(Result);
+ }
+
+ @Test
+ public void checkNewTransNoAvg() {
+
+ Assert.assertNotNull(authzEnv.newTransNoAvg());
+ }
+
+ @Test
+ public void checkNewTrans() {
+ Assert.assertNotNull(authzEnv.newTrans());
+ }
+
+ @Test
+ public void checkPropAccess() {
+ Assert.assertNotNull(authzEnv.access());
+ }
+
+ @Test
+ public void checkgetProperties() { //TODO:[GABE]No setter for this, add?
+ Assert.assertNotNull(authzEnv.getProperties());
+ Assert.assertNotNull(authzEnv.getProperties("test"));
+ }
+
+ @Test(expected = APIException.class)
+ public void checkSetLog4JNames() throws APIException {//TODO: Find better way to test instead of just seeing if strings pass
+ authzEnv.setLog4JNames("path", "root","service","audit","init","trace");
+ authzEnv.setLog4JNames("path", "root",null,"audit","init","trace");
+ }
+
+ @Test
+ public void checkPropertyGetters(){
+ authzEnv.setProperty("key","value");
+ Assert.assertEquals(authzEnv.getProperty("key"), "value");
+ Assert.assertEquals(authzEnv.getProperty("key","value"), "value");
+ }
+
+ @Test
+ public void checkPropertySetters(){
+ Assert.assertEquals(authzEnv.getProperty("key","value"), authzEnv.setProperty("key","value"));
+ }
+
+ @Test(expected = IOException.class)
+ public void testDecryptException() throws IOException{
+ String encrypted = "enc:";
+ authzEnv.setProperty(Config.CADI_KEYFILE, "test");//TODO: Figure out setter for this
+ authzEnv.decrypt(encrypted, true);
+ authzEnv.decrypt("", false);
+ }
+
+ @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);
+ }
+
+ @Test
+ public void testClassLoader() {
+ ClassLoader cLoad = mock(ClassLoader.class);
+ cLoad = authzEnv.classLoader();
+ Assert.assertNotNull(cLoad);
+ }
+
+ @Test
+ public void testLoad() throws IOException {
+ InputStream is = mock(InputStream.class);
+ authzEnv.load(is);
+ }
+
+ @Test
+ public void testLog() {
+ Access.Level lvl = Access.Level.DEBUG;
+ Object msgs = null;
+ authzEnv.log(lvl, msgs);
+ }
+
+ @Test
+ public void testLog1() {
+ Exception e = new Exception();
+ Object msgs = null;
+ authzEnv.log(e, msgs);
+ }
+
+ @Test
+ public void testPrintf() {
+ Access.Level lvl = Access.Level.DEBUG;
+ Object msgs = null;
+ authzEnv.printf(lvl, "Test", msgs);
+ }
+
+ @Test
+ public void testWillLog() {
+ Access.Level lvl = Access.Level.DEBUG;
+ Access.Level lvl1 = Access.Level.AUDIT;
+ boolean test = authzEnv.willLog(lvl);
+ Assert.assertFalse(test);
+ test = authzEnv.willLog(lvl1);
+ Assert.assertTrue(test);
+
+ }
+
+ @Test
+ public void testSetLogLevel() {
+ Access.Level lvl = Access.Level.DEBUG;
+ authzEnv.setLogLevel(lvl);
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransFilter.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransFilter.java
new file mode 100644
index 00000000..f874e9d0
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransFilter.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.env.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.*;
+import org.mockito.Mock;
+import java.security.Principal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.env.AuthzTransFilter;
+import org.onap.aaf.auth.env.AuthzTransImpl;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Connector;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.TrustChecker;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.Trans.Metric;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class JU_AuthzTransFilter {
+AuthzTransFilter authzTransFilter;
+AuthzEnv authzEnvMock = mock(AuthzEnv.class);
+Connector connectorMock = mock(Connector.class);
+TrustChecker trustCheckerMock = mock(TrustChecker.class);
+AuthzTrans authzTransMock = mock(AuthzTrans.class);
+Object additionalTafLurs = mock(Object.class);
+
+ @Before
+ public void setUp() throws CadiException{
+ when(authzEnvMock.access()).thenReturn(new PropAccess());
+ //when(authzEnvMock.newTrans()).thenReturn(new AuthzTransImpl(authzEnvMock));
+ authzTransFilter = new AuthzTransFilter(authzEnvMock, connectorMock, trustCheckerMock, additionalTafLurs);
+
+
+ }
+
+/* @Test
+ public void testTallyHo(){
+ PowerMockito.when(authzTransMock.info().isLoggable()).thenReturn(true);
+ //TODO: Gabe [JUnit] Not visible for junit
+ //if(trans.info().isLoggable())
+ //authzTransFilter.tallyHo(authzTransMock);
+
+ }*/
+
+ /*@Test
+ public void testProtected() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Method newTransMethod = AuthzTransFilter.class.getDeclaredMethod("newTrans");
+ newTransMethod.setAccessible(true);
+
+ newTransMethod.invoke(authzTransFilter);
+ }*/
+
+ @Test
+ public void testAuthenticated() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, CadiException {
+ Principal p = mock(Principal.class);
+ AuthzTransFilter aTF = new AuthzTransFilter(authzEnvMock, connectorMock, trustCheckerMock, null);
+ Class c = aTF.getClass();
+ Class[] cArg = new Class[2];
+ cArg[0] = AuthzTrans.class;
+ cArg[1] = Principal.class; //Steps to test a protected method
+ Method authenticatedMethod = c.getDeclaredMethod("authenticated", cArg);
+ authenticatedMethod.setAccessible(true);
+ authenticatedMethod.invoke(aTF,authzTransMock, null);
+ }
+
+ @Test
+ public void testTallyHo() throws CadiException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Slot specialLogSlot = authzEnvMock.slot("SPECIAL_LOG_SLOT");
+ LogTarget lt = mock(LogTarget.class);
+ AuthzTransFilter aTF = new AuthzTransFilter(authzEnvMock, connectorMock, trustCheckerMock, additionalTafLurs);
+ TaggedPrincipal tPrin = mock(TaggedPrincipal.class);
+ Metric met = new Metric();
+ met.total = 199.33F;
+ met.entries = 15;
+ met.buckets = new float[] {199.33F,99.33F};
+ Class c = aTF.getClass();
+ Class[] cArg = new Class[1];
+ cArg[0] = AuthzTrans.class; //Steps to test a protected method
+ Method tallyHoMethod = c.getDeclaredMethod("tallyHo", cArg);
+ StringBuilder sb = new StringBuilder("AuditTrail\n");
+ when(authzTransMock.auditTrail(((LogTarget)any()), anyInt(),(StringBuilder)any(),anyInt(),anyInt())).thenReturn(met);
+ tallyHoMethod.setAccessible(true);
+ when(authzTransMock.get(specialLogSlot, false)).thenReturn(false);
+ when(authzTransMock.warn()).thenReturn(lt);
+ when(authzTransMock.info()).thenReturn(lt);
+ tallyHoMethod.invoke(aTF,authzTransMock);
+ when(authzTransMock.getUserPrincipal()).thenReturn(tPrin);
+ tallyHoMethod.invoke(aTF,authzTransMock);
+
+ }
+
+
+
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransImpl.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransImpl.java
new file mode 100644
index 00000000..c646e52e
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransImpl.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====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.env.test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.security.Principal;
+import java.util.Date;
+
+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.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTransImpl;
+import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.cadi.Lur;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.LogTarget;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import junit.framework.Assert;
+
+@RunWith(PowerMockRunner.class)
+public class JU_AuthzTransImpl {
+
+ AuthzTransImpl authzTransImpl;
+ @Mock
+ AuthzEnv authzEnvMock;
+ AuthzTransImpl trans1;
+
+ private Organization org=null;
+ private AuthzTransImpl mockAuthzTransImpl;
+ private static HttpServletRequest req;
+ private static HttpServletResponse res;
+ private Lur lur1 = mock(Lur.class);
+
+ @Before
+ public void setUp(){
+ authzTransImpl = new AuthzTransImpl(authzEnvMock);
+ req = mock(HttpServletRequest.class);
+ authzTransImpl.set(req);
+ when(req.getParameter("request")).thenReturn("NotNull");
+ authzTransImpl.set(req);
+ when(req.getParameter("request")).thenReturn("");
+ authzTransImpl.set(req);
+ }
+
+ @Test
+ public void testOrg() {
+ Organization result=null;
+ result = authzTransImpl.org();
+ OrganizationFactory test = mock(OrganizationFactory.class);
+ //result = OrganizationFactory.obtain(authzTransImpl.env(), authzTransImpl.user());
+ authzTransImpl.org();
+ //when(test).thenReturn(null);
+ //assertTrue(true);
+ }
+
+ @Mock
+ LogTarget logTargetMock;
+
+ @Test
+ public void testLogAuditTrail(){
+
+ when(logTargetMock.isLoggable()).thenReturn(false);
+ authzTransImpl.logAuditTrail(logTargetMock);
+ when(logTargetMock.isLoggable()).thenReturn(true);
+ Env delegate = mock(Env.class);
+ //when(logTargetMock.isLoggable()).thenReturn(true);//TODO: Figure this out
+ //authzTransImpl.logAuditTrail(logTargetMock);
+ }
+
+// @Test //TODO:Fix this AAF-111
+// public void testSetUser() {
+// Principal user = mock(Principal.class);
+// authzTransImpl.setUser(user);
+// Principal user1 = authzTransImpl.getUserPrincipal();
+// String username = user1.getName();
+// Assert.assertNotNull(user1);
+// }
+
+// @Test //TODO:Fix this AAF-111
+// public void testUser() {
+// Assert.assertEquals("n/a", authzTransImpl.user());
+// Principal user = mock(Principal.class); //Unsure how to modify name
+// when(user.toString()).thenReturn("name");
+// when(user.getName()).thenReturn("name");
+// authzTransImpl.setUser(user);
+// Assert.assertEquals("name", authzTransImpl.user());
+// }
+//
+ @Test
+ public void testRequested() {
+ REQD_TYPE user = REQD_TYPE.move;
+ REQD_TYPE user1 = REQD_TYPE.future;
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ String p = user1.name();
+ boolean boolUser = authzTransImpl.requested(user);
+ Assert.assertEquals(false, boolUser);
+ Assert.assertNotNull(p);
+ authzTransImpl.requested(user,true);
+ when(authzTransImpl.requested(user)).thenReturn(null);
+ Assert.assertEquals(true, authzTransImpl.requested(user));
+ /* String p1 = req.getParameter(user1.name()); //unable to access private method call in all instances
+ when(req.getParameter(user1.name())).thenReturn("test");
+ authzTransImpl.requested(user,false);
+ */
+
+
+ }
+
+ @Test
+ public void testFish() {
+ mockAuthzTransImpl = mock(AuthzTransImpl.class);
+ Permission p = mock(Permission.class);
+ authzTransImpl.fish(p);
+ String str = "Test";
+ lur1.createPerm(str);
+ when(p.match(p)).thenReturn(true);
+ authzTransImpl.setLur(lur1);
+ authzTransImpl.fish(p);
+ }
+
+ @Test
+ public void testSetVariables() { //TODO: refactor this better
+ Assert.assertNull(authzTransImpl.agent());
+ Assert.assertNull(authzTransImpl.ip());
+ Assert.assertNull(authzTransImpl.path());
+ Assert.assertNotNull(authzTransImpl.port());
+ Assert.assertNull(authzTransImpl.meth());
+ Assert.assertNull(authzTransImpl.getUserPrincipal());
+ Assert.assertNotNull(authzTransImpl.user());
+ }
+
+ @Test
+ public void testNow() {
+ Date date = new Date();
+ Assert.assertEquals(date,authzTransImpl.now());
+ when(authzTransImpl.now()).thenReturn(null);
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransOnlyFilter.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransOnlyFilter.java
new file mode 100644
index 00000000..b29e716a
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_AuthzTransOnlyFilter.java
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.env.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import static org.mockito.Mockito.*;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javax.servlet.ServletRequest;
+
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+import org.onap.aaf.misc.env.Env;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.env.AuthzTransFilter;
+import org.onap.aaf.auth.env.AuthzTransOnlyFilter;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.Connector;
+import org.onap.aaf.cadi.TrustChecker;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.Trans.Metric;
+
+@RunWith(MockitoJUnitRunner.class)
+public class JU_AuthzTransOnlyFilter {
+ AuthzTransFilter authzTransFilter;
+ AuthzEnv authzEnvMock = mock(AuthzEnv.class);
+ Connector connectorMock = mock(Connector.class);
+ TrustChecker trustCheckerMock = mock(TrustChecker.class);
+ AuthzTrans authzTransMock = mock(AuthzTrans.class);
+ Object additionalTafLurs = mock(Object.class);
+ ServletRequest servletRequestMock = mock(ServletRequest.class);
+ AuthzTransOnlyFilter authzTransOnlyFilter;
+
+ @Before
+ public void setUp(){
+ authzTransOnlyFilter = new AuthzTransOnlyFilter(authzEnvMock);
+ }
+
+ /*@Test
+ public void testProtected() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Method newTransMethod = AuthzTransFilter.class.getDeclaredMethod("newTrans");
+ newTransMethod.setAccessible(true);
+
+ newTransMethod.invoke(authzTransFilter);
+ }*/
+
+ @Test
+ public void testStart() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ AuthzTransOnlyFilter aTF = new AuthzTransOnlyFilter(authzEnvMock);
+ Class c = aTF.getClass();
+ Class[] cArg = new Class[2];
+ cArg[0] = AuthzTrans.class;
+ cArg[1] = ServletRequest.class; //Steps to test a protected method
+ Method startMethod = c.getDeclaredMethod("start", cArg);
+ startMethod.setAccessible(true);
+ //startMethod.invoke(aTF, authzTransMock, servletRequestMock);
+ }
+
+ @Test
+ public void testAuthenticated() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, CadiException {
+ TaggedPrincipal p = mock(TaggedPrincipal.class);
+ AuthzTransOnlyFilter aTF = new AuthzTransOnlyFilter(authzEnvMock);
+ Class c = aTF.getClass();
+ Class[] cArg = new Class[2];
+ cArg[0] = AuthzTrans.class;
+ cArg[1] = TaggedPrincipal.class; //Steps to test a protected method
+ Method authenticatedMethod = c.getDeclaredMethod("authenticated", cArg);
+ authenticatedMethod.setAccessible(true);
+ authenticatedMethod.invoke(aTF,authzTransMock, null);
+ }
+
+ @Test
+ public void testTallyHo() throws CadiException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ AuthzTransOnlyFilter aTF = new AuthzTransOnlyFilter(authzEnvMock);
+ LogTarget log = mock(LogTarget.class);
+ Metric met = new Metric();
+ met.total = 199.33F;
+ met.entries = 15;
+ met.buckets = new float[] {199.33F,99.33F};
+ Class c = aTF.getClass();
+ Class[] cArg = new Class[1];
+ cArg[0] = AuthzTrans.class; //Steps to test a protected method
+ StringBuilder sb = new StringBuilder("AuditTrail\n");
+ when(authzTransMock.auditTrail(anyInt(),(StringBuilder)any(),anyInt(),anyInt())).thenReturn(met);
+ when(authzTransMock.info()).thenReturn(log);
+ doNothing().when(log).log((StringBuilder)any());
+ Method tallyHoMethod = c.getDeclaredMethod("tallyHo", cArg);
+ tallyHoMethod.setAccessible(true);
+ tallyHoMethod.invoke(aTF,authzTransMock);
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_NullTrans.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_NullTrans.java
new file mode 100644
index 00000000..e82aa163
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/env/test/JU_NullTrans.java
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.env.test;
+
+import static org.junit.Assert.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+import 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.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.env.NullTrans;
+import org.onap.aaf.auth.env.AuthzTrans.REQD_TYPE;
+import org.onap.aaf.auth.org.Organization;
+import org.onap.aaf.cadi.Permission;
+import org.onap.aaf.misc.env.Decryptor;
+import org.onap.aaf.misc.env.Encryptor;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.Slot;
+import org.onap.aaf.misc.env.TimeTaken;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.security.Principal;
+import java.util.Date;
+
+@RunWith(MockitoJUnitRunner.class)
+public class JU_NullTrans {
+ NullTrans nullTrans;
+
+ @Before
+ public void setUp(){
+ nullTrans = new NullTrans();
+ }
+
+ @Test
+ public void testAuditTrail() {
+ Assert.assertNull(nullTrans.auditTrail(0, null, 0));
+ }
+
+ @Test
+ public void testSingleton() {
+ AuthzTrans single = nullTrans.singleton();
+ Assert.assertTrue(single instanceof AuthzTrans);
+ }
+
+ @Test
+ public void testCheckpoints() {
+ nullTrans.checkpoint("Test");
+ nullTrans.checkpoint(null, 0);
+ }
+
+ @Test
+ public void testFatal() {
+ LogTarget log = nullTrans.fatal();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testError() {
+ LogTarget log = nullTrans.error();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testAudit() {
+ LogTarget log = nullTrans.audit();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testInit() {
+ LogTarget log = nullTrans.init();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testWarn() {
+ LogTarget log = nullTrans.warn();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testInfo() {
+ LogTarget log = nullTrans.info();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testDebug() {
+ LogTarget log = nullTrans.debug();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testTrace() {
+ LogTarget log = nullTrans.trace();
+ Assert.assertEquals(LogTarget.NULL, log);
+ }
+
+ @Test
+ public void testStart() {
+ TimeTaken test = nullTrans.start("test", 1);
+ StringBuilder sb = new StringBuilder();
+ test.output(sb);
+ StringBuilder sb1 = new StringBuilder();
+ sb1.append(test);
+ String s = sb.toString();
+ String s1 = sb1.toString();
+ s1 = s1.trim();
+ Assert.assertEquals(s,s1);
+ }
+
+ @Test
+ public void testSetProperty() {
+ String tag = "tag";
+ String value = "value";
+ nullTrans.setProperty(tag, value);
+ String expected = nullTrans.getProperty(tag, value);
+ Assert.assertEquals(expected, value);
+ String expectedTag = nullTrans.getProperty(tag);
+ Assert.assertEquals(expectedTag, tag);
+ }
+
+ @Test
+ public void testDecryptor() {
+ Decryptor decry = nullTrans.decryptor();
+ Assert.assertNull(decry);
+ }
+
+ @Test
+ public void testEncryptor() {
+ Encryptor encry = nullTrans.encryptor();
+ Assert.assertNull(encry);
+ }
+
+ @Test
+ public void testSet() {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ AuthzTrans set = nullTrans.set(req);
+ Assert.assertNull(set);
+ }
+
+ @Test
+ public void testUser() {
+ String user = nullTrans.user();
+ Assert.assertNull(user);
+ }
+
+ @Test
+ public void testGetUserPrincipal() {
+ Principal principal = nullTrans.getUserPrincipal();
+ Assert.assertNull(principal);
+ }
+
+ @Test
+ public void testIp() {
+ String ip = nullTrans.ip();
+ Assert.assertNull(ip);
+ }
+
+ @Test
+ public void testMeth() {
+ String meth = nullTrans.meth();
+ Assert.assertNull(meth);
+ }
+
+ @Test
+ public void testPort() {
+ int port = nullTrans.port();
+ Assert.assertEquals(port,0);
+ }
+
+ @Test
+ public void testPath() {
+ String path = nullTrans.path();
+ Assert.assertNull(path);
+ }
+
+ @Test
+ public void testPut() {
+ nullTrans.put(null, nullTrans);
+ }
+
+ @Test
+ public void testSetUser() {
+ Principal principal = mock(Principal.class);
+ //nullTrans.setUser(principal);
+ }
+
+ @Test
+ public void testSlot() {
+ Slot slot = nullTrans.slot(null);
+ Assert.assertNull(slot);
+ }
+
+ @Test
+ public void testEnv() {
+ AuthzEnv env = nullTrans.env();
+ Assert.assertNull(env);
+ }
+
+ @Test
+ public void testAgent() {
+ String agent = nullTrans.agent();
+ Assert.assertNull(agent);
+ }
+
+ @Test
+ public void testSetLur() {
+ nullTrans.setLur(null);
+ }
+
+ @Test
+ public void testFish() {
+ Permission perm = mock(Permission.class);
+ Boolean fish = nullTrans.fish(perm);
+ Assert.assertFalse(fish);
+ }
+
+ @Test
+ public void testOrg() {
+ Organization org = nullTrans.org();
+ Assert.assertEquals(Organization.NULL, org);
+ }
+
+ @Test
+ public void testLogAuditTrail() {
+ LogTarget lt = mock(LogTarget.class);
+ nullTrans.logAuditTrail(lt);
+ }
+
+ @Test
+ public void testRequested() {
+ Boolean reqd = nullTrans.requested(null);
+ Assert.assertFalse(reqd);
+ nullTrans.requested(null, true);
+ }
+
+ @Test
+ public void testNow() {
+ Date date = new Date();
+ Assert.assertEquals(date,nullTrans.now());
+ //when(nullTrans.now()).thenReturn(null);
+ }
+
+
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/layer/test/JU_Result.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/layer/test/JU_Result.java
new file mode 100644
index 00000000..fc812a2c
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/layer/test/JU_Result.java
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.layer.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.onap.aaf.auth.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(){
+ //TODO: Gabe [JUnit] Not visible for junit
+ //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());
+//
+// }
+
+ @Test
+ public void netYetTested() {
+ fail("Tests not yet implemented");
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_DataFile.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_DataFile.java
new file mode 100644
index 00000000..a7ea2953
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_DataFile.java
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+package org.onap.aaf.auth.local.test;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import static org.junit.Assert.*;
+import org.junit.AfterClass;
+import org.junit.Test;
+import org.onap.aaf.auth.local.DataFile;
+import org.onap.aaf.auth.local.DataFile.Token;
+import org.onap.aaf.auth.local.DataFile.Token.Field;
+
+public class JU_DataFile {
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ @Test
+ public void netYetTested() {
+ fail("Tests not yet implemented");
+ }
+
+// @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/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_TextIndex.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_TextIndex.java
new file mode 100644
index 00000000..613d2a80
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/local/test/JU_TextIndex.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.local.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.aaf.auth.local.DataFile;
+import org.onap.aaf.auth.local.TextIndex;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+
+@RunWith(MockitoJUnitRunner.class)
+public class JU_TextIndex {
+ TextIndex textIndex;
+ Trans trans;
+ DataFile datefile;
+ @Mock
+ File file;
+
+ @Before
+ public void setUp() throws IOException{ //TODO: AAF-111 fix once actual input is known.
+ char character = 'a';
+ String filePath = "test/output_key";
+ File keyfile = new File(filePath);
+ FileOutputStream is = new FileOutputStream(keyfile);
+ OutputStreamWriter osw = new OutputStreamWriter(is);
+ Writer w = new BufferedWriter(osw);
+ w.write("asdfasdfasdf");
+ w.close();
+ datefile = new DataFile(keyfile, "test");
+ trans = mock(Trans.class);
+ textIndex = new TextIndex(keyfile);
+ //textIndex.create(trans, datefile, 20, character, 2, 2);
+ keyfile.delete();
+ }
+
+ @Test
+ public void testOpen() throws IOException {
+ //textIndex.open();
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationException.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationException.java
new file mode 100644
index 00000000..01b8256f
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationException.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.org.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aaf.auth.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/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationFactory.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationFactory.java
new file mode 100644
index 00000000..2136e786
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/org/test/JU_OrganizationFactory.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====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.org.test;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import static org.mockito.Mockito.mock;
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.org.OrganizationFactory;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.impl.BasicEnv;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class JU_OrganizationFactory {
+ private static final String ORG_SLOT = null;
+ OrganizationFactory organizationFactory;
+ BasicEnv bEnv;
+ @Mock
+ AuthzEnv authzEnvMock;
+ String orgClass="orgclass";
+ String orgNS="orgns";
+ @Before
+ public void setUp(){
+ organizationFactory = new OrganizationFactory();
+ bEnv = new BasicEnv();
+ }
+
+ @SuppressWarnings("static-access")
+ @Test(expected = APIException.class)
+ public void testInit() throws OrganizationException {
+ organizationFactory.init(bEnv);
+ }
+
+// @SuppressWarnings("static-access") TODO:Fix this AAF-111
+// @Test(expected = OrganizationException.class)
+// public void testObtain() throws OrganizationException{
+// PowerMockito.when(authzEnvMock.getProperty("Organization."+orgNS)).thenReturn("notnull");
+// organizationFactory.obtain(authzEnvMock, orgNS);
+// }
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/CredCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/CredCompare.java
new file mode 100644
index 00000000..cac26a88
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/CredCompare.java
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.*;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.CredRequest;
+
+public class CredCompare extends RosettaCompare<CredRequest> {
+ public CredCompare() {
+ super(CredRequest.class);
+ }
+
+ public static CredRequest create() {
+ CredRequest rr = new CredRequest();
+ String in = instance();
+ rr.setId("m888"+ in + "@ns.att.com");
+ rr.setPassword("Bogus0"+in);
+ rr.setType(200);
+ GregorianCalendar gc = new GregorianCalendar();
+ rr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ rr.setEnd(Chrono.timeStamp(gc));
+ return rr;
+ }
+
+ @Override
+ public void compare(CredRequest t1, CredRequest t2) {
+ assertEquals(t1.getId(),t2.getId());
+ assertEquals(t1.getPassword(),t2.getPassword());
+ assertEquals(t1.getType(),t2.getType());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public CredRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/JU_RequestCheck.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/JU_RequestCheck.java
new file mode 100644
index 00000000..38bd51fc
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/JU_RequestCheck.java
@@ -0,0 +1,42 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import org.junit.Test;
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+public class JU_RequestCheck {
+
+ @Test
+ public void testNSRequest() throws APIException {
+ RosettaEnv env = new RosettaEnv();
+ new NSCompare().run(env);
+ new NSAttribCompare().run(env);
+ new RoleCompare().run(env);
+ new PermCompare().run(env);
+ new CredCompare().run(env);
+ new UserRoleCompare().run(env);
+ new RolePermCompare().run(env);
+ new MultiCompare().run(env);
+ };
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/MultiCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/MultiCompare.java
new file mode 100644
index 00000000..5450bf55
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/MultiCompare.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.assertEquals;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.MultiRequest;
+
+public class MultiCompare extends RosettaCompare<MultiRequest> {
+ public MultiCompare() {
+ super(MultiRequest.class);
+ }
+
+ @Override
+ public MultiRequest newOne() {
+ MultiRequest multi = new MultiRequest();
+ multi.setNsRequest(NSCompare.create());
+ multi.getNsAttribRequest().add(NSAttribCompare.create());
+ multi.getNsAttribRequest().add(NSAttribCompare.create());
+ multi.getRoleRequest().add(RoleCompare.create());
+ multi.getRoleRequest().add(RoleCompare.create());
+ multi.getPermRequest().add(PermCompare.create());
+ multi.getPermRequest().add(PermCompare.create());
+ multi.getCredRequest().add(CredCompare.create());
+ multi.getCredRequest().add(CredCompare.create());
+ multi.getUserRoleRequest().add(UserRoleCompare.create());
+ multi.getUserRoleRequest().add(UserRoleCompare.create());
+ multi.getRolePermRequest().add(RolePermCompare.create());
+ multi.getRolePermRequest().add(RolePermCompare.create());
+
+
+ GregorianCalendar gc = new GregorianCalendar();
+ multi.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ multi.setEnd(Chrono.timeStamp(gc));
+ return multi;
+ }
+
+ public void compare(MultiRequest t1, MultiRequest t2) {
+ new NSCompare().compare(t1.getNsRequest(), t2.getNsRequest());
+ // Will have to find by key for others.
+
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSAttribCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSAttribCompare.java
new file mode 100644
index 00000000..9f6ce21e
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSAttribCompare.java
@@ -0,0 +1,93 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.NsAttribRequest;
+import aaf.v2_0.NsAttribRequest.Attrib;
+
+public class NSAttribCompare extends RosettaCompare<NsAttribRequest> {
+ public NSAttribCompare() {
+ super(NsAttribRequest.class);
+ }
+
+ public static NsAttribRequest create() {
+ NsAttribRequest nar = new NsAttribRequest();
+ String in = instance();
+
+ nar.setNs("org.osaaf.ns"+in);
+ Attrib attrib = new Attrib();
+ attrib.setKey("swm");
+ attrib.setValue("v"+instance());
+ nar.getAttrib().add(attrib);
+ attrib = new Attrib();
+ attrib.setKey("scamp");
+ attrib.setValue("v"+instance());
+ nar.getAttrib().add(attrib);
+ GregorianCalendar gc = new GregorianCalendar();
+ nar.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ nar.setEnd(Chrono.timeStamp(gc));
+ return nar;
+ }
+
+ @Override
+ public void compare(NsAttribRequest t1, NsAttribRequest t2) {
+ assertEquals(t1.getNs(),t2.getNs());
+ for(Attrib a1 : t1.getAttrib()) {
+ boolean ok = false;
+ for(Attrib a2 : t2.getAttrib()) {
+ if(a1.getKey().equals(a2.getKey()) &&
+ a1.getValue().equals(a2.getValue())) {
+ ok = true;
+ break;
+ }
+ }
+ assertTrue("a2 Attribs in a1",ok);
+ }
+ for(Attrib a2 : t2.getAttrib()) {
+ boolean ok = false;
+ for(Attrib a1 : t1.getAttrib()) {
+ if(a1.getKey().equals(a2.getKey()) &&
+ a1.getValue().equals(a2.getValue())) {
+ ok = true;
+ break;
+ }
+ }
+ assertTrue("a2 Attribs in a1",ok);
+ }
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public NsAttribRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSCompare.java
new file mode 100644
index 00000000..b7fc28cc
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/NSCompare.java
@@ -0,0 +1,75 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.NsRequest;
+
+public class NSCompare extends RosettaCompare<NsRequest> {
+ public NSCompare() {
+ super(NsRequest.class);
+ }
+
+ public static NsRequest create() {
+ NsRequest nsr = new NsRequest();
+ String in = instance();
+ nsr.setName("org.osaaf.ns"+in);
+ nsr.setDescription("Hello World"+in);
+ nsr.getAdmin().add("Fred"+in);
+ nsr.getAdmin().add("Barney"+in);
+ nsr.getResponsible().add("Wilma"+in);
+ nsr.getResponsible().add("Betty"+in);
+ nsr.setType("Hello"+in);
+ GregorianCalendar gc = new GregorianCalendar();
+ nsr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ nsr.setEnd(Chrono.timeStamp(gc));
+ return nsr;
+ }
+
+ @Override
+ public void compare(NsRequest t1, NsRequest t2) {
+ assertEquals(t1.getName(),t2.getName());
+ assertEquals(t1.getDescription(),t2.getDescription());
+ for(String s : t1.getAdmin()) {
+ assertTrue(t2.getAdmin().contains(s));
+ }
+ for(String s : t2.getAdmin()) {
+ assertTrue(t1.getAdmin().contains(s));
+ }
+ assertEquals(t1.getType(),t2.getType());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public NsRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/PermCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/PermCompare.java
new file mode 100644
index 00000000..3d9a9fdb
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/PermCompare.java
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.*;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.PermRequest;
+
+public class PermCompare extends RosettaCompare<PermRequest> {
+ public PermCompare() {
+ super(PermRequest.class);
+ }
+
+ public static PermRequest create() {
+ PermRequest pr = new PermRequest();
+ String in = instance();
+ pr.setType("org.osaaf.ns.perm"+in);
+ pr.setInstance("instance"+in);
+ pr.setAction("read");
+ pr.setDescription("Hello World, Perm"+in);
+ GregorianCalendar gc = new GregorianCalendar();
+ pr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ pr.setEnd(Chrono.timeStamp(gc));
+ return pr;
+ }
+
+ @Override
+ public void compare(PermRequest t1, PermRequest t2) {
+ assertEquals(t1.getType(),t2.getType());
+ assertEquals(t1.getInstance(),t2.getInstance());
+ assertEquals(t1.getAction(),t2.getAction());
+ assertEquals(t1.getDescription(),t2.getDescription());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public PermRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RoleCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RoleCompare.java
new file mode 100644
index 00000000..35bd3370
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RoleCompare.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.*;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.RoleRequest;
+
+public class RoleCompare extends RosettaCompare<RoleRequest> {
+ public RoleCompare() {
+ super(RoleRequest.class);
+ }
+
+ public static RoleRequest create() {
+ RoleRequest rr = new RoleRequest();
+ String in = instance();
+ rr.setName("org.osaaf.ns.role"+in);
+ rr.setDescription("Hello World, Role"+in);
+ GregorianCalendar gc = new GregorianCalendar();
+ rr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ rr.setEnd(Chrono.timeStamp(gc));
+ return rr;
+ }
+
+ @Override
+ public void compare(RoleRequest t1, RoleRequest t2) {
+ assertEquals(t1.getName(),t2.getName());
+ assertEquals(t1.getDescription(),t2.getDescription());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public RoleRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RolePermCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RolePermCompare.java
new file mode 100644
index 00000000..d6ea98b9
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RolePermCompare.java
@@ -0,0 +1,69 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.assertEquals;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.Pkey;
+import aaf.v2_0.RolePermRequest;
+
+public class RolePermCompare extends RosettaCompare<RolePermRequest> {
+ public RolePermCompare() {
+ super(RolePermRequest.class);
+ }
+
+ public static RolePermRequest create() {
+ RolePermRequest urr = new RolePermRequest();
+ String in = instance();
+ urr.setRole("org.osaaf.ns.role"+in);
+ Pkey pkey = new Pkey();
+ pkey.setType("org.osaaf.ns.myType"+in);
+ pkey.setInstance("myInstance"+in);
+ pkey.setAction("myAction"+in);
+ urr.setPerm(pkey);
+ GregorianCalendar gc = new GregorianCalendar();
+ urr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ urr.setEnd(Chrono.timeStamp(gc));
+ return urr;
+ }
+
+ @Override
+ public void compare(RolePermRequest t1, RolePermRequest t2) {
+ assertEquals(t1.getRole(),t2.getRole());
+ assertEquals(t1.getPerm().getType(),t1.getPerm().getType());
+ assertEquals(t1.getPerm().getInstance(),t1.getPerm().getInstance());
+ assertEquals(t1.getPerm().getAction(),t1.getPerm().getAction());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public RolePermRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RosettaCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RosettaCompare.java
new file mode 100644
index 00000000..5130f8cb
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/RosettaCompare.java
@@ -0,0 +1,66 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import org.onap.aaf.misc.env.APIException;
+import org.onap.aaf.misc.env.Data;
+import org.onap.aaf.misc.env.Data.TYPE;
+import org.onap.aaf.misc.rosetta.env.RosettaDF;
+import org.onap.aaf.misc.rosetta.env.RosettaData;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+
+public abstract class RosettaCompare<T> {
+ protected Class<T> cls;
+ private static int count = 0;
+
+ public RosettaCompare(Class<T> cls) {
+ this.cls = cls;
+ }
+
+ public void run(RosettaEnv env) throws APIException {
+ RosettaDF<T> nsrDF = env.newDataFactory(cls);
+ compare(nsrDF.newData().option(Data.PRETTY),newOne(),this);
+ }
+
+ private void compare(RosettaData<T> rdt, T t, RosettaCompare<T> comp) throws APIException {
+ System.out.println("########### Testing " + cls.getName() + " ##############");
+ String s = rdt.load(t).out(TYPE.JSON).asString();
+ System.out.println(s);
+ T t2 = rdt.in(TYPE.JSON).load(s).asObject();
+ comp.compare(t, t2);
+
+ System.out.println();
+
+ s = rdt.load(t).out(TYPE.XML).asString();
+ System.out.println(s);
+ t2 = rdt.in(TYPE.XML).load(s).asObject();
+ comp.compare(t, t2);
+ }
+
+ public synchronized static String instance() {
+ return "_"+ ++count;
+ }
+
+ public abstract void compare(T t1, T t2);
+ public abstract T newOne();
+
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/UserRoleCompare.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/UserRoleCompare.java
new file mode 100644
index 00000000..542ddeb7
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/request/test/UserRoleCompare.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.request.test;
+
+import static junit.framework.Assert.*;
+
+import java.util.GregorianCalendar;
+
+import org.onap.aaf.misc.env.util.Chrono;
+
+import aaf.v2_0.UserRoleRequest;
+
+public class UserRoleCompare extends RosettaCompare<UserRoleRequest> {
+ public UserRoleCompare() {
+ super(UserRoleRequest.class);
+ }
+
+ public static UserRoleRequest create() {
+ UserRoleRequest urr = new UserRoleRequest();
+ String in = instance();
+ urr.setUser("m125"+in + "@ns.att.com");
+ urr.setRole("org.osaaf.ns.role"+in);
+ GregorianCalendar gc = new GregorianCalendar();
+ urr.setStart(Chrono.timeStamp(gc));
+ gc.add(GregorianCalendar.MONTH, 1);
+ urr.setEnd(Chrono.timeStamp(gc));
+ return urr;
+ }
+
+ @Override
+ public void compare(UserRoleRequest t1, UserRoleRequest t2) {
+ assertEquals(t1.getUser(),t2.getUser());
+ assertEquals(t1.getRole(),t2.getRole());
+ assertEquals(t1.getStart(),t2.getStart());
+ assertEquals(t1.getEnd(),t2.getEnd());
+ }
+
+
+ @Override
+ public UserRoleRequest newOne() {
+ return create();
+ }
+} \ No newline at end of file
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch.java
new file mode 100644
index 00000000..af1d289e
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch.java
@@ -0,0 +1,173 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.aaf.auth.rserv.Match;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.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"));
+
+ }
+
+ @Test
+ public void testGetParamNames() {
+ Match bm = new Match("/req/1.0.0/:var");
+ Set s = bm.getParamNames();
+ Assert.assertNotNull(s);
+ }
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch1.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch1.java
new file mode 100644
index 00000000..e104009a
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterMatch1.java
@@ -0,0 +1,164 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.auth.rserv.Match;
+import org.onap.aaf.misc.env.Env;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.impl.EnvFactory;
+
+
+public class JU_BetterMatch1 {
+
+ @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("whatever/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/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterRoute.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterRoute.java
new file mode 100644
index 00000000..d98cf5ce
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_BetterRoute.java
@@ -0,0 +1,33 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.rserv.test;
+
+import org.junit.Test;
+
+public class JU_BetterRoute {
+
+ @Test
+ public void test() {
+
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CachingFileAccess.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CachingFileAccess.java
new file mode 100644
index 00000000..26e9717f
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CachingFileAccess.java
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.*;
+import static org.mockito.Matchers.*;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.reflect.Field;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.NavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.mockito.Mock;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aaf.auth.rserv.CachingFileAccess;
+import org.onap.aaf.auth.rserv.HttpCode;
+import org.onap.aaf.auth.rserv.Match;
+
+//import org.onap.aaf.auth.rserv.CachingFileAccess.Content;
+import java.util.NavigableMap;
+import org.onap.aaf.misc.env.EnvJAXB;
+import org.onap.aaf.misc.env.LogTarget;
+import org.onap.aaf.misc.env.StaticSlot;
+import org.onap.aaf.misc.env.Store;
+import org.onap.aaf.misc.env.Trans;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import junit.framework.Assert;
+
+
+@RunWith(PowerMockRunner.class)
+public class JU_CachingFileAccess {
+ CachingFileAccess cachingFileAccess;
+ HttpCode httpCode;
+ EnvJAXB envJ;
+ Trans trans;
+
+
+ @Before
+ public void setUp() throws IOException{
+ trans = mock(Trans.class);
+ HttpCode hCode = mock(HttpCode.class);
+ envJ = mock(EnvJAXB.class);
+ LogTarget log = mock(LogTarget.class);
+ Long lng = (long) 1234134;
+ when(envJ.get(envJ.staticSlot("aaf_cfa_cache_check_interval"),600000L)).thenReturn(lng);
+ when(envJ.get(envJ.staticSlot("aaf_cfa_max_size"), 512000)).thenReturn(512000);
+ when(envJ.get(envJ.staticSlot("aaf_cfa_web_path"))).thenReturn("TEST");
+ when(envJ.getProperty("aaf_cfa_clear_command",null)).thenReturn("null");
+ when(envJ.init()).thenReturn(log);
+ doNothing().when(log).log((String)any());
+ cachingFileAccess = new CachingFileAccess(envJ,"test");
+
+
+
+ }
+
+ @Test
+ public void testSetEnv() {
+ Store store = mock(Store.class);
+ Store store1 = mock(Store.class);
+ Store store2 = mock(Store.class);
+ String test[] = {"aaf_cfa_web_path","aaf_cfa_cache_check_interval","aaf_cfa_max_size"};
+ String test1[] = {"aaf_cfa_cache_check_interval"};
+ String test2[] = {"aaf_cfa_max_size"};
+ cachingFileAccess.setEnv(store, test);
+ cachingFileAccess.setEnv(store1, test1); //These don't reach all the branches for some reason
+ cachingFileAccess.setEnv(store2, test2);
+ }
+
+ @Test
+ public void testHandle() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
+ HttpServletRequest req = mock(HttpServletRequest.class);
+ Trans trans = mock(Trans.class);
+ HttpServletResponse resp = mock(HttpServletResponse.class);
+ when(req.getPathInfo()).thenReturn("path/to/file");
+
+ Field matchField = HttpCode.class.getDeclaredField("match");
+ matchField.setAccessible(true);
+ Match match = mock(Match.class);
+ when(match.param(anyString(), anyString())).thenReturn("null/");
+ matchField.set(cachingFileAccess, match);
+ cachingFileAccess.handle(trans, req, resp);
+ when(match.param(anyString(), anyString())).thenReturn("clear");
+ cachingFileAccess.handle(trans, req, resp);
+ }
+
+ @Test
+ public void testWebPath() {
+ EnvJAXB envJ = mock(EnvJAXB.class);
+ String web_path_test = "TEST";
+ Assert.assertEquals(web_path_test, cachingFileAccess.webPath());
+ }
+
+ @Test
+ public void testCleanupParams() {
+ NavigableMap<String,org.onap.aaf.auth.rserv.Content> content = new ConcurrentSkipListMap<String,org.onap.aaf.auth.rserv.Content>();
+ cachingFileAccess.cleanupParams(50, 500); //TODO: find right input
+ }
+
+ @Test
+ public void testLoad() throws IOException {
+ cachingFileAccess.load(null, null, "1220227200L/1220227200L", null, 1320227200L );
+ String filePath = "test/output_key";
+ File keyfile = new File(filePath);
+ RandomAccessFile randFile = new RandomAccessFile (keyfile,"rw");
+
+ String dPath = "test/";
+ File directoryPath = new File(dPath);
+ directoryPath.mkdir();
+ cachingFileAccess.load(null, dPath, "-", null, -1);
+ randFile.setLength(1024 * 1024 * 8);
+ cachingFileAccess.load(null, filePath, "-", null, -1);
+ keyfile.delete();
+ directoryPath.delete();
+ String filePath1 = "test/output_key";
+ File keyfile1 = new File(filePath1);
+ keyfile1.createNewFile();
+ cachingFileAccess.load(null, filePath1, "-", "test", -1);
+ keyfile1.delete();
+ }
+
+ @Test
+ public void testLoadOrDefault() throws IOException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, ClassNotFoundException, InstantiationException {
+ String filePath = "test/output_key";
+ File keyfile = new File(filePath);
+ cachingFileAccess.loadOrDefault(trans, filePath, "-", null, null);
+ keyfile.delete();
+
+ Trans trans = mock(Trans.class);
+
+ String filePath1 = "test/output_key.txt";
+ //File keyfile1 = new File(filePath1);
+ doAnswer(new Answer<Void>() {
+ public Void answer(InvocationOnMock invocation) throws FileNotFoundException {
+ throw new FileNotFoundException();
+ }
+ }).when(trans).info();
+ //cachingFileAccess.loadOrDefault(trans, "bs", "also bs", "test", null); //TODO: Needs more testing AAF-111
+ //keyfile1.delete();
+ }
+
+ @Test
+ public void testInvalidate() {
+ //NavigableMap<String,org.onap.aaf.auth.rserv.Content> content = new ConcurrentSkipListMap<String,org.onap.aaf.auth.rserv.Content>();
+ //Content con = mock(Content.class);
+ //content.put("hello", con);
+ cachingFileAccess.invalidate("hello");
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CodeSetter.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CodeSetter.java
new file mode 100644
index 00000000..75d1df8f
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_CodeSetter.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+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.auth.rserv.CodeSetter;
+import org.onap.aaf.auth.rserv.Route;
+import org.onap.aaf.misc.env.Trans;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class JU_CodeSetter {
+ //TODO: Gabe [JUnit] Not visible for junit
+ //CodeSetter codeSetter;
+ @Mock
+ Trans transMock;
+ @Mock
+ HttpServletRequest reqMock;
+ @Mock
+ HttpServletResponse respMock;
+
+// @Before //TODO: Fix this AAF-111
+// 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);
+// }
+
+ @Test
+ public void netYetTested() {
+ fail("Tests not yet implemented");
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content.java
new file mode 100644
index 00000000..c2be2eb1
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content.java
@@ -0,0 +1,661 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.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.auth.rserv.HttpCode;
+import org.onap.aaf.auth.rserv.TypedCode;
+import org.onap.aaf.misc.env.TransJAXB;
+import org.onap.aaf.misc.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);
+ }
+ }
+//
+// Original API used HTTPServletRequest and HTTPServletResponse. Due to the fact that sometimes we use Accept, and others Content-TYpe
+// I changed it to simply accept a string
+//
+// Jonathan 3/8/2013
+//
+// @SuppressWarnings("rawtypes")
+// class BogusReq implements HttpServletRequest {
+// private String accept;
+//
+// public void accept(String accept) {
+// this.accept = accept;
+// }
+//
+// @Override
+// public Object getAttribute(String name) {
+// return accept;
+// }
+//
+//
+// @Override
+// public Enumeration getAttributeNames() {
+// return null;
+// }
+//
+// @Override
+// public String getCharacterEncoding() {
+// return null;
+// }
+//
+// @Override
+// public void setCharacterEncoding(String env)
+// throws UnsupportedEncodingException {
+//
+//
+// }
+//
+// @Override
+// public int getContentLength() {
+//
+// return 0;
+// }
+//
+// @Override
+// public String getContentType() {
+//
+// return null;
+// }
+//
+// @Override
+// public ServletInputStream getInputStream() throws IOException {
+//
+// return null;
+// }
+//
+// @Override
+// public String getParameter(String name) {
+//
+// return null;
+// }
+//
+// @Override
+// public Enumeration getParameterNames() {
+//
+// return null;
+// }
+//
+// @Override
+// public String[] getParameterValues(String name) {
+//
+// return null;
+// }
+//
+// @Override
+// public Map getParameterMap() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getProtocol() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getScheme() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getServerName() {
+//
+// return null;
+// }
+//
+// @Override
+// public int getServerPort() {
+//
+// return 0;
+// }
+//
+// @Override
+// public BufferedReader getReader() throws IOException {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRemoteAddr() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRemoteHost() {
+//
+// return null;
+// }
+//
+// @Override
+// public void setAttribute(String name, Object o) {
+//
+//
+// }
+//
+// @Override
+// public void removeAttribute(String name) {
+//
+//
+// }
+//
+// @Override
+// public Locale getLocale() {
+//
+// return null;
+// }
+//
+// @Override
+// public Enumeration getLocales() {
+//
+// return null;
+// }
+//
+// @Override
+// public boolean isSecure() {
+//
+// return false;
+// }
+//
+// @Override
+// public RequestDispatcher getRequestDispatcher(String path) {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRealPath(String path) {
+//
+// return null;
+// }
+//
+// @Override
+// public int getRemotePort() {
+//
+// return 0;
+// }
+//
+// @Override
+// public String getLocalName() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getLocalAddr() {
+//
+// return null;
+// }
+//
+// @Override
+// public int getLocalPort() {
+//
+// return 0;
+// }
+//
+// @Override
+// public String getAuthType() {
+//
+// return null;
+// }
+//
+// @Override
+// public Cookie[] getCookies() {
+//
+// return null;
+// }
+//
+// @Override
+// public long getDateHeader(String name) {
+//
+// return 0;
+// }
+//
+// @Override
+// public String getHeader(String name) {
+// return accept;
+// }
+//
+// @Override
+// public Enumeration getHeaders(String name) {
+//
+// return null;
+// }
+//
+// @Override
+// public Enumeration getHeaderNames() {
+//
+// return null;
+// }
+//
+// @Override
+// public int getIntHeader(String name) {
+//
+// return 0;
+// }
+//
+// @Override
+// public String getMethod() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getPathInfo() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getPathTranslated() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getContextPath() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getQueryString() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRemoteUser() {
+//
+// return null;
+// }
+//
+// @Override
+// public boolean isUserInRole(String role) {
+//
+// return false;
+// }
+//
+// @Override
+// public Principal getUserPrincipal() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRequestedSessionId() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getRequestURI() {
+//
+// return null;
+// }
+//
+// @Override
+// public StringBuffer getRequestURL() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getServletPath() {
+//
+// return null;
+// }
+//
+// @Override
+// public HttpSession getSession(boolean create) {
+//
+// return null;
+// }
+//
+// @Override
+// public HttpSession getSession() {
+//
+// return null;
+// }
+//
+// @Override
+// public boolean isRequestedSessionIdValid() {
+//
+// return false;
+// }
+//
+// @Override
+// public boolean isRequestedSessionIdFromCookie() {
+//
+// return false;
+// }
+//
+// @Override
+// public boolean isRequestedSessionIdFromURL() {
+//
+// return false;
+// }
+//
+// @Override
+// public boolean isRequestedSessionIdFromUrl() {
+//
+// return false;
+// }
+// }
+//
+// public class BogusResp implements HttpServletResponse {
+// public String contentType;
+//
+// @Override
+// public String getCharacterEncoding() {
+//
+// return null;
+// }
+//
+// @Override
+// public String getContentType() {
+// return contentType;
+// }
+//
+// @Override
+// public ServletOutputStream getOutputStream() throws IOException {
+//
+// return null;
+// }
+//
+// @Override
+// public PrintWriter getWriter() throws IOException {
+//
+// return null;
+// }
+//
+// @Override
+// public void setCharacterEncoding(String charset) {
+//
+//
+// }
+//
+// @Override
+// public void setContentLength(int len) {
+//
+//
+// }
+//
+// @Override
+// public void setContentType(String type) {
+// contentType = type;
+// }
+//
+// @Override
+// public void setBufferSize(int size) {
+//
+//
+// }
+//
+// @Override
+// public int getBufferSize() {
+//
+// return 0;
+// }
+//
+// @Override
+// public void flushBuffer() throws IOException {
+//
+//
+// }
+//
+// @Override
+// public void resetBuffer() {
+//
+//
+// }
+//
+// @Override
+// public boolean isCommitted() {
+//
+// return false;
+// }
+//
+// @Override
+// public void reset() {
+//
+//
+// }
+//
+// @Override
+// public void setLocale(Locale loc) {
+//
+//
+// }
+//
+// @Override
+// public Locale getLocale() {
+//
+// return null;
+// }
+//
+// @Override
+// public void addCookie(Cookie cookie) {
+//
+//
+// }
+//
+// @Override
+// public boolean containsHeader(String name) {
+//
+// return false;
+// }
+//
+// @Override
+// public String encodeURL(String url) {
+//
+// return null;
+// }
+//
+// @Override
+// public String encodeRedirectURL(String url) {
+//
+// return null;
+// }
+//
+// @Override
+// public String encodeUrl(String url) {
+//
+// return null;
+// }
+//
+// @Override
+// public String encodeRedirectUrl(String url) {
+//
+// return null;
+// }
+//
+// @Override
+// public void sendError(int sc, String msg) throws IOException {
+//
+//
+// }
+//
+// @Override
+// public void sendError(int sc) throws IOException {
+//
+//
+// }
+//
+// @Override
+// public void sendRedirect(String location) throws IOException {
+//
+//
+// }
+//
+// @Override
+// public void setDateHeader(String name, long date) {
+//
+//
+// }
+//
+// @Override
+// public void addDateHeader(String name, long date) {
+//
+//
+// }
+//
+// @Override
+// public void setHeader(String name, String value) {
+//
+//
+// }
+//
+// @Override
+// public void addHeader(String name, String value) {
+//
+//
+// }
+//
+// @Override
+// public void setIntHeader(String name, int value) {
+//
+//
+// }
+//
+// @Override
+// public void addIntHeader(String name, int value) {
+//
+//
+// }
+//
+// @Override
+// public void setStatus(int sc) {
+//
+//
+// }
+//
+// @Override
+// public void setStatus(int sc, String sm) {
+//
+//
+// }
+//
+// }
+//
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content1.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content1.java
new file mode 100644
index 00000000..4d640d09
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Content1.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.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.auth.rserv.HttpCode;
+import org.onap.aaf.auth.rserv.TypedCode;
+import org.onap.aaf.misc.env.TransJAXB;
+import org.onap.aaf.misc.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_Content1 {
+
+
+ @Test
+ public void test() throws Exception {
+ final String BOOL = "Boolean";
+ final String XML = "XML";
+ TransJAXB trans = EnvFactory.newTrans();
+ try {
+ HttpCode<TransJAXB, String> cBool = new HttpCode<TransJAXB,String>(BOOL,"Standard String") {
+ @Override
+ public void handle(TransJAXB trans, HttpServletRequest req, HttpServletResponse resp) {
+ try {
+ resp.getOutputStream().write(context.getBytes());
+ } catch (IOException e) {
+ }
+ }
+ };
+
+ HttpCode<TransJAXB,String> cXML = new HttpCode<TransJAXB,String>(XML, "Standard String") {
+ @Override
+ public void handle(TransJAXB trans, HttpServletRequest req, HttpServletResponse resp) {
+ try {
+ resp.getOutputStream().write(context.getBytes());
+ } catch (IOException e) {
+ }
+ }
+ };
+
+ TypedCode<TransJAXB> ct = new TypedCode<TransJAXB>()
+ .add(cBool,"application/" + Boolean.class.getName()+"+xml;charset=utf8;version=1.1")
+ .add(cXML,"application/xml;q=.9");
+ String expected = "application/java.lang.Boolean+xml;charset=utf8;version=1.1,application/xml;q=0.9";
+ assertEquals(expected,ct.toString());
+
+ //BogusReq req = new BogusReq();
+ //expected = (expected);
+ //HttpServletResponse resp = new BogusResp();
+
+ assertNotNull("Same Content String and Accept String",ct.prep(trans,expected));
+
+ //expects Null (not run)
+ // A Boolean xml that must have charset utf8 and match version 1.2 or greater
+ expected = ("application/java.lang.Boolean+xml;charset=utf8;version=1.2");
+ assertNull("Accept Minor Version greater than Content Minor Version",ct.prep(trans,expected));
+
+ // Same with (too many) spaces
+ expected = (" application/java.lang.Boolean+xml ; charset = utf8 ; version = 1.2 ");
+ assertNull("Accept Minor Version greater than Content Minor Version",ct.prep(trans,expected));
+
+ //expects Null (not run)
+ expected = ("application/java.lang.Boolean+xml;charset=utf8;version=2.1");
+ assertNull("Major Versions not the same",ct.prep(trans,expected));
+
+ expected = ("application/java.lang.Boolean+xml;charset=utf8;version=1.0");
+ assertNotNull("Content Minor Version is greater than Accept Minor Version",ct.prep(trans,expected));
+
+ expected = "application/java.lang.Squid+xml;charset=utf8;version=1.0,application/xml;q=.9";
+ assertNotNull("2nd one will have to do...",ct.prep(trans,expected));
+
+ expected = "application/java.lang.Boolean+xml;charset=UTF8;version=1.0";
+ assertNotNull("Minor Charset in Caps acceptable",ct.prep(trans,expected));
+
+ // expects no run
+ expected="application/java.lang.Boolean+xml;charset=MyType;version=1.0";
+ assertNull("Unknown Minor Charset",ct.prep(trans,expected));
+
+ expected="";
+ assertNotNull("Blank Acceptance",ct.prep(trans,expected));
+
+ expected=null;
+ assertNotNull("Null Acceptance",ct.prep(trans,expected));
+
+ expected = ("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
+ assertNotNull("Matches application/xml, and other content not known",ct.prep(trans,expected));
+
+ // No SemiColon
+ expected = ("i/am/bogus,application/xml");
+ assertNotNull("Match second entry, with no Semis",ct.prep(trans,expected));
+
+ } finally {
+ StringBuilder sb = new StringBuilder();
+ trans.auditTrail(0, sb);
+ System.out.println(sb);
+ }
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Pair.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Pair.java
new file mode 100644
index 00000000..557c7ec5
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Pair.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====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.aaf.auth.rserv.Pair;
+
+import junit.framework.Assert;
+
+public class JU_Pair {
+ Pair<Integer, Integer> pair;
+ Integer x;
+ Integer y;
+
+ @Before
+ public void setUp(){
+ pair = new Pair<Integer, Integer>(1, 2);
+ }
+
+ @Test
+ public void testToString() {
+ String result = pair.toString();
+ Assert.assertEquals("X: " + pair.x.toString() + "-->" + pair.y.toString(), result);
+ }
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Route.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Route.java
new file mode 100644
index 00000000..d5953b10
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Route.java
@@ -0,0 +1,38 @@
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+import org.junit.Before;
+import static org.mockito.Matchers.*;
+import static org.mockito.Mockito.*;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.onap.aaf.auth.rserv.Route;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.auth.rserv.*;
+
+public class JU_Route {
+ Route route;
+ HttpCode httpCode;
+ HttpMethods httpMethod;
+ Trans trans;
+
+ @Before
+ public void setUp() { //TODO: AAF-111 complete when actual input is provided
+ //httpMethod = Matchers.any(HttpMethods.class);
+ //when(httpMethod.name()).thenReturn("test");
+ // route = new Route(null,"path/to/place");
+ }
+
+
+ @Test
+ public void testAdd() {
+ // route.add(httpCode, "path/to/place");
+ }
+
+ @Test
+ public void testStart() {
+ // trans = mock(Trans.class);
+ // route.start(trans, "test", httpCode, "test");
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_RouteReport.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_RouteReport.java
new file mode 100644
index 00000000..a9fdff60
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_RouteReport.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+import org.onap.aaf.auth.rserv.RouteReport;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class JU_RouteReport {
+
+ @Test
+ public void test() {
+ RouteReport report;
+ report = new RouteReport();
+ Assert.assertNotNull(report);
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Routes.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Routes.java
new file mode 100644
index 00000000..2ed08841
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/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====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+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 static org.mockito.Mockito.*;
+//import org.onap.aaf.auth.rserv.CodeSetter;
+import org.onap.aaf.auth.rserv.Route;
+import org.onap.aaf.auth.rserv.Routes;
+import org.onap.aaf.misc.env.Trans;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class JU_Routes {
+ Routes routes;
+ @Mock
+ HttpServletRequest reqMock;
+ //TODO: Gabe [JUnit] Not visible to junit
+ //CodeSetter<Trans> codeSetterMock;
+ Route<Trans> routeObj;
+
+ @Before
+ public void setUp(){
+ routes = new Routes();
+ }
+
+ @Test
+ public void testRouteReport(){
+ List listVal = routes.routeReport();
+ assertNotNull(listVal);
+ }
+
+ @Test
+ public void testDerive() throws IOException, ServletException{
+ routeObj = routes.derive(reqMock, null);
+
+ }
+
+
+
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_TypedCode.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_TypedCode.java
new file mode 100644
index 00000000..d5b57de0
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_TypedCode.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Matchers.anyString;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+//import org.onap.aaf.auth.rserv.Acceptor;
+import org.onap.aaf.auth.rserv.HttpCode;
+import org.onap.aaf.auth.rserv.HttpMethods;
+import org.onap.aaf.auth.rserv.RouteReport;
+import org.onap.aaf.auth.rserv.TypedCode;
+import org.onap.aaf.misc.env.TimeTaken;
+import org.onap.aaf.misc.env.Trans;
+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);
+ }
+
+ @Test
+ public void testAdd() {
+ HttpCode<?, ?> code = mock(HttpCode.class);
+ typedCode.add(code , "test", "test1", "test2");
+ }
+
+ @Test
+ public void testPrep() throws IOException, ServletException, ClassNotFoundException {
+ Trans trans = mock(Trans.class);
+ TimeTaken time = new TimeTaken("yell", 2) {
+ @Override
+ public void output(StringBuilder sb) {
+ // TODO Auto-generated method stub
+ }
+ };
+ when(trans.start(";na=me;,prop", 8)).thenReturn(time);
+ HttpCode<?, ?> code = mock(HttpCode.class);
+ code.pathParam(null, null);
+ code.isAuthorized(null); //Testing httpcode, currently not working
+ code.no_cache();
+ code.toString();
+
+ typedCode.add(code , "");
+ typedCode.prep(null , "q");
+
+ typedCode.add(code , "t");
+ typedCode.prep(trans , null);
+
+ typedCode.add(code , "t");
+ typedCode.prep(trans , "");
+
+ typedCode.add(code, "POST /authn/validate application/CredRequest+json;charset=utf-8;version=2.0,application/json;version=2.0,*/*");
+ //typedCode.prep(trans , "POST /authn/validate application/CredRequest+json;charset=utf-8;version=2.0,application/json;version=2.0,*/*");
+ }
+
+ @Test
+ public void testRelatedTo() {
+ HttpCode<?, ?> code = mock(HttpCode.class);
+ StringBuilder sb = new StringBuilder();
+ typedCode.relatedTo(code, sb);
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Version.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Version.java
new file mode 100644
index 00000000..617fa259
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/rserv/test/JU_Version.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====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.rserv.test;
+
+import static org.junit.Assert.*;
+
+import 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.auth.rserv.Version;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+public class JU_Version {
+ Version version;
+ Version versionTest;
+
+
+ @Before
+ public void setUp(){
+ version = new Version("first\\.123");
+ versionTest = new Version("first\\.124");
+ }
+
+ @Test
+ public void testEquals(){
+ version.equals(versionTest);
+ versionTest.equals(version);
+ versionTest = new Version("fail\\.124");
+ version.equals(versionTest);
+ version.equals("This is not an object of version");
+ versionTest = new Version("NoVersion\\.number");
+ version.equals(versionTest);
+
+
+ }
+
+ @Test
+ public void testToString(){
+ String strVal = version.toString();
+ assertNotNull(strVal);
+ }
+
+ @Test
+ public void testHashCode() {
+ Assert.assertNotNull(version.hashCode());
+ }
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/server/test/JU_JettyServiceStarter.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/server/test/JU_JettyServiceStarter.java
new file mode 100644
index 00000000..463d558d
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/server/test/JU_JettyServiceStarter.java
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.server.test;
+
+import static org.junit.Assert.*;
+
+import org.onap.aaf.auth.env.AuthzEnv;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.org.OrganizationException;
+import org.onap.aaf.auth.server.AbsService;
+import org.onap.aaf.auth.server.JettyServiceStarter;
+import org.onap.aaf.cadi.Access;
+import org.onap.aaf.cadi.CadiException;
+import org.onap.aaf.cadi.LocatorException;
+import org.onap.aaf.cadi.PropAccess;
+import org.onap.aaf.cadi.register.Registrant;
+import org.onap.aaf.misc.env.Trans;
+import org.onap.aaf.misc.env.impl.BasicEnv;
+import org.onap.aaf.misc.rosetta.env.RosettaEnv;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.Filter;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+public class JU_JettyServiceStarter {
+ private PropAccess propAccess = new PropAccess();
+ private JettyServiceStarter<AuthzEnv,AuthzTrans> jss;
+ class TestService extends AbsService{
+
+ public TestService(Access access, BasicEnv env) throws CadiException {
+ super(access, env);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public Filter[] filters() throws CadiException, LocatorException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Registrant[] registrants(int port) throws CadiException, LocatorException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+ @SuppressWarnings("unchecked")
+ @Before
+ public void setUp() throws OrganizationException, CadiException {
+ Access access = mock(Access.class);
+
+ BasicEnv bEnv = mock(BasicEnv.class);
+ Trans trans = mock(Trans.class); //TODO: Fix this once Gabe has services running to see correct output without mock
+ //TestService testService = new TestService(access, bEnv);
+ //jss = new JettyServiceStarter<AuthzEnv,AuthzTrans>(testService);
+ }
+
+ @Test
+ public void netYetTested() {
+ fail("Tests not yet implemented");
+ }
+
+ @Test
+ public void testPropertyAdjustment() {
+ //jss._propertyAdjustment();
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/util/test/JU_Mask.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/util/test/JU_Mask.java
new file mode 100644
index 00000000..535664bd
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/util/test/JU_Mask.java
@@ -0,0 +1,71 @@
+/**
+ * ============LICENSE_START====================================================
+ * org.onap.aaf
+ * ===========================================================================
+ * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
+ * ===========================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END====================================================
+ *
+ */
+
+package org.onap.aaf.auth.util.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.net.InetAddress;
+
+import org.junit.Test;
+import org.onap.aaf.cadi.util.MaskFormatException;
+import org.onap.aaf.cadi.util.NetMask;
+
+import junit.framework.Assert;
+
+public class JU_Mask {
+
+ @Test
+ public void test() throws Exception {
+ InetAddress ia = InetAddress.getLocalHost();
+ NetMask mask = new NetMask(ia.getAddress());
+ assertTrue(mask.isInNet(ia.getAddress()));
+
+ mask = new NetMask("192.168.1/24");
+ assertTrue(mask.isInNet("192.168.1.20"));
+ assertTrue(mask.isInNet("192.168.1.255"));
+ assertFalse(mask.isInNet("192.168.2.20"));
+
+ mask = new NetMask("192.168.1/31");
+ assertFalse(mask.isInNet("192.168.2.20"));
+ assertFalse(mask.isInNet("192.168.1.20"));
+ assertTrue(mask.isInNet("192.168.1.1"));
+ assertFalse(mask.isInNet("192.168.1.2"));
+
+ mask = new NetMask("192/8");
+ assertTrue(mask.isInNet("192.168.1.1"));
+ assertTrue(mask.isInNet("192.1.1.1"));
+ assertFalse(mask.isInNet("193.168.1.1"));
+
+ mask = new NetMask("/0");
+ assertTrue(mask.isInNet("193.168.1.1"));
+
+ String msg = "Should throw " + MaskFormatException.class.getSimpleName();
+ try {
+ mask = new NetMask("256.256.256.256");
+ Assert.assertTrue(msg,false);
+ } catch (MaskFormatException e) {
+ Assert.assertTrue(msg,true);
+ }
+ }
+
+}
diff --git a/auth/auth-core/src/test/java/org/onap/aaf/auth/validation/test/JU_Validator.java b/auth/auth-core/src/test/java/org/onap/aaf/auth/validation/test/JU_Validator.java
new file mode 100644
index 00000000..fb59a54d
--- /dev/null
+++ b/auth/auth-core/src/test/java/org/onap/aaf/auth/validation/test/JU_Validator.java
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * ============LICENSE_START====================================================
+ * * org.onap.aaf
+ * * ===========================================================================
+ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * * ===========================================================================
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * * you may not use this file except in compliance with the License.
+ * * You may obtain a copy of the License at
+ * *
+ * * http://www.apache.org/licenses/LICENSE-2.0
+ * *
+ * * Unless required by applicable law or agreed to in writing, software
+ * * distributed under the License is distributed on an "AS IS" BASIS,
+ * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * * See the License for the specific language governing permissions and
+ * * limitations under the License.
+ * * ============LICENSE_END====================================================
+ * *
+ * *
+ ******************************************************************************/
+package org.onap.aaf.auth.validation.test;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.regex.Pattern;
+
+import static org.mockito.Matchers.*;
+import org.mockito.Mock;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.Test;
+import org.onap.aaf.auth.env.AuthzTrans;
+import org.onap.aaf.auth.env.AuthzTransOnlyFilter;
+import org.onap.aaf.auth.validation.Validator;
+import org.onap.aaf.cadi.principal.TaggedPrincipal;
+
+public class JU_Validator {
+
+ Validator validator;
+
+ @Before
+ public void setUp() {
+ validator = new Validator();
+ }
+
+ @Test
+ public void testNullOrBlank() {
+ validator.nullOrBlank(null, "str");
+ validator.nullOrBlank("test", "");
+ validator.nullOrBlank("test", null);
+ }
+
+ @Test
+ public void testIsNull() {
+ Object o = new Object();
+ validator.isNull(null, null);
+ validator.isNull(null, o);
+ }
+
+ @Test
+ public void testDescription() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+ Class c = validator.getClass();
+ Class[] cArg = new Class[2];
+ cArg[0] = String.class;
+ cArg[1] = String.class; //Steps to test a protected method
+ Method descriptionMethod = c.getDeclaredMethod("description", cArg);
+ descriptionMethod.setAccessible(true);
+ descriptionMethod.invoke(validator,"test", "test1");
+ descriptionMethod.invoke(validator,null, null);
+ descriptionMethod.invoke(validator,null, "[\\\\x25\\\\x28\\\\x29\\\\x2C-\\\\x2E\\\\x30-\\\\x39\\\\x3D\\\\x40-\\\\x5A\\\\x5F\\\\x61-\\\\x7A\\\\x20]+");
+
+
+ }
+
+ @Test
+ public void test() {
+ assertTrue(Validator.ACTION_CHARS.matcher("HowdyDoody").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("Howd?yDoody").matches());
+ assertTrue(Validator.ACTION_CHARS.matcher("_HowdyDoody").matches());
+ assertTrue(Validator.INST_CHARS.matcher("HowdyDoody").matches());
+ assertFalse(Validator.INST_CHARS.matcher("Howd?yDoody").matches());
+ assertTrue(Validator.INST_CHARS.matcher("_HowdyDoody").matches());
+
+ //
+ assertTrue(Validator.ACTION_CHARS.matcher("*").matches());
+ assertTrue(Validator.INST_CHARS.matcher("*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":*:*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":*:*").matches());
+
+ assertFalse(Validator.ACTION_CHARS.matcher(":hello").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":hello").matches());
+ assertFalse(Validator.INST_CHARS.matcher("hello:").matches());
+ assertFalse(Validator.INST_CHARS.matcher("hello:d").matches());
+
+ assertFalse(Validator.ACTION_CHARS.matcher(":hello:*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":hello:*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":hello:d*:*").matches());
+ assertFalse(Validator.INST_CHARS.matcher(":hello:d*d:*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":hello:d*:*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("HowdyDoody*").matches());
+ assertFalse(Validator.INST_CHARS.matcher("Howdy*Doody").matches());
+ assertTrue(Validator.INST_CHARS.matcher("HowdyDoody*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("*HowdyDoody").matches());
+ assertFalse(Validator.INST_CHARS.matcher("*HowdyDoody").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":h*").matches());
+ assertFalse(Validator.INST_CHARS.matcher(":h*h*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":h*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":h:h*:*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":h:h*:*").matches());
+ assertFalse(Validator.INST_CHARS.matcher(":h:h*h:*").matches());
+ assertFalse(Validator.INST_CHARS.matcher(":h:h*h*:*").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":h:*:*h").matches());
+ assertFalse(Validator.INST_CHARS.matcher(":h:*:*h").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":com.test.*:ns:*").matches());
+
+
+ assertFalse(Validator.ACTION_CHARS.matcher("1234+235gd").matches());
+ assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd").matches());
+ assertTrue(Validator.ACTION_CHARS.matcher("1234-23_5gd").matches());
+ assertTrue(Validator.ACTION_CHARS.matcher("1234-235g,d").matches());
+ assertTrue(Validator.ACTION_CHARS.matcher("1234-235gd(Version12)").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("123#4-23@5g:d").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("1234-23 5gd").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("1234-235gd ").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(" 1234-235gd").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(" ").matches());
+
+ // Allow % and = (Needed for Escaping & Base64 usages) jg
+ assertTrue(Validator.ACTION_CHARS.matcher("1234%235g=d").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher(":1234%235g=d").matches());
+ assertTrue(Validator.INST_CHARS.matcher("1234%235g=d").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:%20==").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:=%23").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:*:=%23").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":1234%235g=d:==%20:*").matches());
+ assertTrue(Validator.INST_CHARS.matcher(":*:==%20:*").matches());
+
+ // Allow / instead of : (more natural instance expression) jg
+ assertFalse(Validator.INST_CHARS.matcher("1234/a").matches());
+ assertTrue(Validator.INST_CHARS.matcher("/1234/a").matches());
+ assertTrue(Validator.INST_CHARS.matcher("/1234/*/a/").matches());
+ assertTrue(Validator.INST_CHARS.matcher("/1234//a").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("1234/a").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("/1234/*/a/").matches());
+ assertFalse(Validator.ACTION_CHARS.matcher("1234//a").matches());
+
+
+ assertFalse(Validator.INST_CHARS.matcher("1234+235gd").matches());
+ assertTrue(Validator.INST_CHARS.matcher("1234-235gd").matches());
+ assertTrue(Validator.INST_CHARS.matcher("1234-23_5gd").matches());
+ assertTrue(Validator.INST_CHARS.matcher("1234-235g,d").matches());
+ assertTrue(Validator.INST_CHARS.matcher("m1234@shb.dd.com").matches());
+ assertTrue(Validator.INST_CHARS.matcher("1234-235gd(Version12)").matches());
+ assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());
+ assertFalse(Validator.INST_CHARS.matcher("123#4-23@5g:d").matches());
+ assertFalse(Validator.INST_CHARS.matcher("").matches());
+
+
+ for( char c=0x20;c<0x7F;++c) {
+ boolean b;
+ switch(c) {
+ case '?':
+ case '|':
+ case '*':
+ continue; // test separately
+ case '~':
+ case ',':
+ b = false;
+ break;
+ default:
+ b=true;
+ }
+ }
+
+ assertFalse(Validator.ID_CHARS.matcher("abc").matches());
+ assertFalse(Validator.ID_CHARS.matcher("").matches());
+ assertTrue(Validator.ID_CHARS.matcher("abc@att.com").matches());
+ assertTrue(Validator.ID_CHARS.matcher("ab-me@att.com").matches());
+ assertTrue(Validator.ID_CHARS.matcher("ab-me_.x@att._-com").matches());
+
+ assertFalse(Validator.NAME_CHARS.matcher("ab-me_.x@att._-com").matches());
+ assertTrue(Validator.NAME_CHARS.matcher("ab-me").matches());
+ assertTrue(Validator.NAME_CHARS.matcher("ab-me_.xatt._-com").matches());
+
+
+ // 7/22/2016
+ assertTrue(Validator.INST_CHARS.matcher(
+ "/!com.att.*/role/write").matches());
+ assertTrue(Validator.INST_CHARS.matcher(
+ ":!com.att.*:role:write").matches());
+
+ }
+
+}
diff --git a/auth/auth-core/test/sample.identities.dat b/auth/auth-core/test/sample.identities.dat
new file mode 100644
index 00000000..39d18a12
--- /dev/null
+++ b/auth/auth-core/test/sample.identities.dat
@@ -0,0 +1,27 @@
+#
+# Sample Identities.dat
+# This file is for use with the "Default Organization". It is a simple mechanism to have a basic ILM structure to use with
+# out-of-the-box tire-kicking, or even for Small companies
+#
+# For Larger Companies, you will want to create a new class implementing the "Organization" interface, making calls to your ILM, or utilizing
+# batch feeds, as is appropriate for your company.
+#
+# Example Field Layout. note, in this example, Application IDs and People IDs are mixed. You may want to split
+# out AppIDs, choose your own status indicators, or whatever you use.
+# 0 - unique ID
+# 1 - full name
+# 2 - first name
+# 3 - last name
+# 4 - phone
+# 5 - official email
+# 6 - employment status e=employee, c=contractor, a=application, n=no longer with company
+# 7 - responsible to (i.e Supervisor for People, or AppOwner, if it's an App ID)
+#
+
+iowna|Ima D. Owner|Ima|Owner|314-123-2000|ima.d.owner@osaaf.com|e|
+mmanager|Mark D. Manager|Mark|Manager|314-123-1234|mark.d.manager@osaaf.com|e|iowna
+bdevl|Robert D. Developer|Bob|Developer|314-123-1235|bob.d.develper@osaaf.com|e|mmanager
+mmarket|Mary D. Marketer|Mary|Marketer|314-123-1236|mary.d.marketer@osaaf.com|e|mmanager
+ccontra|Clarice D. Contractor|Clarice|Contractor|314-123-1237|clarice.d.contractor@osaaf.com|c|mmanager
+iretired|Ira Lee M. Retired|Ira|Retired|314-123-1238|clarice.d.contractor@osaaf.com|n|mmanager
+osaaf|ID of AAF|||||a|bdevl