Replace CADI for access to AAF 68/96368/3
authorJerry Flood <jflood@att.com>
Sat, 28 Sep 2019 11:01:17 +0000 (07:01 -0400)
committerJerry Flood <jflood@att.com>
Sat, 28 Sep 2019 15:05:12 +0000 (11:05 -0400)
Issue-ID: OPTFRA-593
Change-Id: I56ee7ea9bebce402541b1acefb5e1049b50ad886
Signed-off-by: Jerry Flood <jflood@att.com>
19 files changed:
cmso-service/etc/config/cmso.properties
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java [deleted file]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java [deleted file]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPerm.java [changed mode: 0644->0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java [moved from cmso-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java with 73% similarity, mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRole.java [changed mode: 0644->0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafUserRoleProperties.java [changed mode: 0644->0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java [new file with mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java [moved from cmso-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java with 64% similarity, mode: 0755]
cmso-service/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java [moved from cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java with 79% similarity, mode: 0755]
cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json [new file with mode: 0644]
cmso-service/src/main/resources/application.properties
cmso-ticketmgt/src/main/resources/application.properties

index ed06d92..6ae215d 100644 (file)
@@ -100,3 +100,8 @@ mechid.user=oof@oof.onap.org
 mechid.pass=enc:vfxQdJ1mgdcI7S6SPrzNaw==\r
 \r
 cmso.dispatch.url=http://localhost:8089\r
+\r
+aaf.urls=https://aaf-onap-test.osaaf.org:8095\r
+aaf.user.role.properties=src/main/resources/aaf/AAFUserRoles.properties\r
+aaf.enabled=true\r
+aaf.namespace=org.onap.oof
\ No newline at end of file
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthProvider.java
new file mode 100755 (executable)
index 0000000..c34e4b0
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import java.util.ArrayList;\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.security.authentication.AuthenticationProvider;\r
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\r
+import org.springframework.security.core.Authentication;\r
+import org.springframework.security.core.AuthenticationException;\r
+import org.springframework.security.web.authentication.WebAuthenticationDetails;\r
+import org.springframework.stereotype.Component;\r
+\r
+@Component\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class AafAuthProvider implements AuthenticationProvider {\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    @Autowired\r
+    AafClientCache clientCache;\r
+\r
+    @Override\r
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {\r
+        String name = authentication.getName();\r
+        String password = authentication.getCredentials().toString();\r
+        String sessionId = null;\r
+        Object details = authentication.getDetails();\r
+        if (details instanceof WebAuthenticationDetails) {\r
+            WebAuthenticationDetails webAuthDetails = (WebAuthenticationDetails) details;\r
+            if (webAuthDetails.getSessionId() != null) {\r
+                sessionId = webAuthDetails.getRemoteAddress() + ":" + webAuthDetails.getSessionId();\r
+            }\r
+        }\r
+        if (env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) {\r
+            if (clientCache.authenticate(name, password, sessionId) != AuthorizationResult.Authenticated) {\r
+                return null;\r
+            }\r
+        }\r
+        return new UsernamePasswordAuthenticationToken(name, password, new ArrayList<>());\r
+\r
+    }\r
+\r
+    @Override\r
+    public boolean supports(Class<?> authentication) {\r
+        return authentication.equals(UsernamePasswordAuthenticationToken.class);\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafAuthorizationFilter.java
deleted file mode 100644 (file)
index c38a53d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import java.io.IOException;
-import java.util.List;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.onap.aaf.cadi.CadiWrap;
-import org.onap.aaf.cadi.Permission;
-import org.onap.observations.Observation;
-import org.onap.optf.cmso.SpringProfiles;
-import org.onap.optf.cmso.common.LogMessages;
-import org.onap.optf.cmso.common.exceptions.CmsoException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-
-/**
- * AAF authorization filter.
- */
-
-@Component
-@Profile(SpringProfiles.AAF_AUTHENTICATION)
-public class AafAuthorizationFilter extends OrderedRequestContextFilter {
-
-    @Autowired
-    AafUserRoleProperties userRoleProperties;
-
-    /**
-     * Instantiates a new aaf authorization filter.
-     */
-    public AafAuthorizationFilter() {
-        this.setOrder(FilterPriority.AAF_AUTHORIZATION.getPriority());
-
-
-    }
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-                    throws IOException, ServletException {
-        try {
-            if (request instanceof CadiWrap) {
-                CadiWrap cw = (CadiWrap) request;
-                List<Permission> perms = cw.getPermissions(cw.getUserPrincipal());
-                if (userRoleProperties.processPermissions(request, perms)) {
-                    filterChain.doFilter(request, response);
-                } else {
-                    Observation.report(LogMessages.UNAUTHORIZED);
-                    ResponseFormatter.errorResponse(request, response, new CmsoException(
-                                    LogMessages.UNAUTHORIZED.getStatus(), LogMessages.UNAUTHORIZED, ""));
-                }
-            } else {
-                throw new Exception();
-            }
-        } catch (Exception e) {
-            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
-            ResponseFormatter.errorResponse(request, response,
-                            new CmsoException(LogMessages.UNAUTHORIZED.getStatus(), LogMessages.UNAUTHORIZED, ""));
-        }
-    }
-}
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClient.java
new file mode 100755 (executable)
index 0000000..e52d295
--- /dev/null
@@ -0,0 +1,184 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import java.net.UnknownHostException;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import java.util.Map;\r
+import javax.ws.rs.ProcessingException;\r
+import javax.ws.rs.client.Client;\r
+import javax.ws.rs.client.ClientBuilder;\r
+import javax.ws.rs.client.Invocation;\r
+import javax.ws.rs.client.WebTarget;\r
+import javax.ws.rs.core.MediaType;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.Response.Status;\r
+import org.onap.observations.Mdc;\r
+import org.onap.observations.Observation;\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.onap.optf.cmso.common.BasicAuthenticatorFilter;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.onap.optf.cmso.common.PropertiesManagement;\r
+import org.onap.optf.cmso.common.exceptions.CmsoException;\r
+import org.onap.optf.cmso.filters.CmsoClientFilters;\r
+import org.onap.optf.cmso.service.rs.models.HealthCheckComponent;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Component;\r
+\r
+@Component\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class AafClient {\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    @Autowired\r
+    PropertiesManagement pm;\r
+\r
+    @Autowired\r
+    AafEndpoints aafEndpoints;\r
+\r
+    /**\r
+     * Gets the authz.\r
+     *\r
+     * @param auth the auth\r
+     * @return the authz\r
+     * @throws CmsoException the cmso exception\r
+     */\r
+    public Response getAuthz(Map<String, String> auth) throws CmsoException {\r
+        Response response = null;\r
+        List<String> endpoints = new ArrayList<>();\r
+        String url = aafEndpoints.getEndpoint(AafEndpoints.Endpoint.AUTHZ, endpoints);\r
+        String user = auth.get("user");\r
+        if (!user.contains("@")) {\r
+            user += env.getProperty(AafProperties.aafDefaultUserDomain.toString(), "@csp.att.com");\r
+        }\r
+        String pass = auth.get("password");\r
+        while (url != null) {\r
+            try {\r
+                // Cannot provide changeId. Interesting.\r
+                // This should be replaced by fetch\r
+                // For now, make a best effort to get the passed changeId\r
+                if (!url.endsWith("/")) {\r
+                    url += "/";\r
+                }\r
+                url += user;\r
+                response = get(url, user, pass);\r
+                return response;\r
+            } catch (ProcessingException e) {\r
+                Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());\r
+                url = aafEndpoints.getNextEndpoint(AafEndpoints.Endpoint.AUTHZ, endpoints);\r
+                if (url == null || !tryNextUrl(e)) {\r
+                    throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNEXPECTED_EXCEPTION, user,\r
+                                    e.getMessage());\r
+                }\r
+            } catch (Exception e) {\r
+                Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());\r
+                throw new CmsoException(Status.INTERNAL_SERVER_ERROR, LogMessages.UNEXPECTED_EXCEPTION, user,\r
+                                e.getMessage());\r
+            }\r
+        }\r
+        return response;\r
+    }\r
+\r
+    /**\r
+     * Gets the.\r
+     *\r
+     * @param url the url\r
+     * @param user the user\r
+     * @param pass the pass\r
+     * @return the response\r
+     */\r
+    public Response get(String url, String user, String pass) {\r
+        Client client = ClientBuilder.newClient();\r
+        client.register(new BasicAuthenticatorFilter(user, pass));\r
+        client.register(new CmsoClientFilters());\r
+        WebTarget target = client.target(url);\r
+        Invocation.Builder invocationBuilder = target.request(MediaType.APPLICATION_JSON);\r
+        debug.debug("AAF URL = " + url);\r
+        Response response = invocationBuilder.get();\r
+        debug.debug("AAF URL = " + url + " user=" + user + ":" + response.getStatusInfo().toString());\r
+        return response;\r
+    }\r
+\r
+    private boolean tryNextUrl(ProcessingException exc) {\r
+        if (exc.getCause() instanceof UnknownHostException) {\r
+            return true;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * Health check.\r
+     *\r
+     * @return the health check component\r
+     */\r
+    public HealthCheckComponent healthCheck() {\r
+        Map<String, String> mdcSave = Mdc.save();\r
+        HealthCheckComponent hcc = new HealthCheckComponent();\r
+        hcc.setName("AAF");\r
+        hcc.setHealthy(false);\r
+        List<String> endpoints = new ArrayList<>();\r
+        try {\r
+            String url = aafEndpoints.getEndpoint(AafEndpoints.Endpoint.HEALTHCHECK, endpoints);\r
+            String user = "";\r
+            String pass = "";\r
+\r
+            while (url != null) {\r
+                try {\r
+                    hcc.setUrl(url);\r
+                    Response response = get(url, user, pass);\r
+                    hcc.setHealthy(true);\r
+                    hcc.setStatus(response.getStatusInfo().toString());\r
+                } catch (ProcessingException e) {\r
+                    Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());\r
+                    url = aafEndpoints.getNextEndpoint(AafEndpoints.Endpoint.HEALTHCHECK, endpoints);\r
+                    if (url == null || !tryNextUrl(e)) {\r
+                        hcc.setStatus(e.getMessage());\r
+                    }\r
+                } catch (Exception e) {\r
+                    Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());\r
+                    hcc.setStatus(e.getMessage());\r
+                }\r
+            }\r
+        } finally {\r
+            Mdc.restore(mdcSave);\r
+        }\r
+        return hcc;\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java
new file mode 100755 (executable)
index 0000000..c76463d
--- /dev/null
@@ -0,0 +1,265 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property. Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except\r
+ * in compliance with the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software distributed under the License\r
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express\r
+ * or implied. See the License for the specific language governing permissions and limitations under\r
+ * the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed under the Creative\r
+ * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except\r
+ * in compliance with the License. You may obtain a copy of the License at\r
+ *\r
+ * https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation distributed under the\r
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either\r
+ * express or implied. See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import java.security.Principal;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import javax.ws.rs.container.ContainerRequestContext;\r
+import javax.ws.rs.core.Response;\r
+import javax.xml.bind.DatatypeConverter;\r
+import org.onap.observations.Observation;\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\r
+import org.springframework.security.web.authentication.WebAuthenticationDetails;\r
+import org.springframework.stereotype.Component;\r
+\r
+/**\r
+ * The Class AafClientCache.\r
+ */\r
+@Component\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class AafClientCache {\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    @Autowired\r
+    AafClient aafClient;\r
+\r
+    @Autowired\r
+    AafUserRoleProperties aafUserRoleProperties;\r
+\r
+    public enum AuthorizationResult {\r
+\r
+        Authorized(0), AuthenticationFailure(401), AuthorizationFailure(403), Authenticated(0),;\r
+        private final int status;\r
+\r
+        AuthorizationResult(int status) {\r
+            this.status = status;\r
+        }\r
+\r
+        public int getStatus() {\r
+            return status;\r
+        }\r
+    }\r
+\r
+    private Map<String, String> cache = new HashMap<>();\r
+    private Long cacheAge = 0L;\r
+\r
+    /**\r
+     * Authorize.\r
+     *\r
+     * @param requestContext the request context\r
+     * @return the authorization result\r
+     */\r
+    public AuthorizationResult authorize(ContainerRequestContext requestContext) {\r
+        if (!env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) {\r
+            return AuthorizationResult.Authorized;\r
+        }\r
+        Map<String, String> auth = getUserPasssword(requestContext);\r
+        String permissions = getPermissions(auth);\r
+        if (permissions == null) {\r
+            return AuthorizationResult.AuthenticationFailure;\r
+        }\r
+        return processPermissions(auth, permissions);\r
+    }\r
+\r
+    /**\r
+     * Authenticate.\r
+     *\r
+     * @param user the user\r
+     * @param password the password\r
+     * @param sessionId the session id\r
+     * @return the authorization result\r
+     */\r
+    public AuthorizationResult authenticate(String user, String password, String sessionId) {\r
+        Map<String, String> auth = new HashMap<>();\r
+        auth.put("user", user);\r
+        auth.put("password", password);\r
+        if (sessionId != null) {\r
+            auth.put("sessionId", sessionId);\r
+        }\r
+        if (getPermissions(auth) == null) {\r
+            return AuthorizationResult.AuthenticationFailure;\r
+        }\r
+        return AuthorizationResult.Authenticated;\r
+    }\r
+\r
+\r
+    private String getPermissions(Map<String, String> auth) {\r
+        long now = System.currentTimeMillis();\r
+        Long timeout = env.getProperty(AafProperties.aafCacheTimeout.toString(), Long.class, 300L);\r
+        String permissions = null;\r
+        // Do caching logic\r
+        // Serializes calls to AAF\r
+        // We will not cache authentication failures...\r
+        synchronized (cache) {\r
+            debug.debug("AAF cache now=" + now + ", cacheAge=" + cacheAge + " timeout=" + timeout);\r
+            if (cacheAge != 0 && now > (cacheAge + (timeout * 1000))) {\r
+                debug.debug("Clearing the AAF cache now=" + now + ", cacheAge=" + cacheAge + " timeout=" + timeout);\r
+                cache.clear();\r
+                cacheAge = now;\r
+            }\r
+            if (cacheAge == 0) {\r
+                cacheAge = now;\r
+            }\r
+            permissions = cache.get(getCacheKey(auth));\r
+            if (permissions == null) {\r
+                if (!auth.get("password").equals("")) {\r
+                    permissions = getPermissionsFromAaf(auth);\r
+                    if (permissions != null) {\r
+                        cache.put(getCacheKey(auth), permissions);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return permissions;\r
+    }\r
+\r
+    private String getCacheKey(Map<String, String> auth) {\r
+        if (auth.get("sessionId") != null) {\r
+            return auth.get("user") + "|" + auth.get("sessionId");\r
+        }\r
+        return auth.get("user") + "|" + auth.get("password");\r
+    }\r
+\r
+\r
+    private String getPermissionsFromAaf(Map<String, String> auth) {\r
+        try {\r
+            Response response = aafClient.getAuthz(auth);\r
+            debug.debug("AAF authorization: " + response.getStatusInfo().toString());\r
+            switch (response.getStatus()) {\r
+                case 200:\r
+                    String permissions = response.readEntity(String.class);\r
+                    return permissions;\r
+                case 401:\r
+                    return null;\r
+                default:\r
+                    Observation.report(LogMessages.UNEXPECTED_RESPONSE, "AAF", response.getStatusInfo().toString(),\r
+                                    auth.get("user"));\r
+            }\r
+        } catch (Exception e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private AuthorizationResult processPermissions(Map<String, String> auth, String permissions) {\r
+        try {\r
+            List<AafUserRole> perms = aafUserRoleProperties.getForUrlMethod(auth.get("path"), auth.get("method"));\r
+            ObjectMapper om = new ObjectMapper();\r
+            AafPermResponse resp = om.readValue(permissions, AafPermResponse.class);\r
+            int tested = 0;\r
+            int passed = 0;\r
+            for (AafUserRole perm : perms) {\r
+                for (AafPerm test : perm.getAafPerms()) {\r
+                    tested++;\r
+                    for (AafPerm userPerm : resp.getPerm()) {\r
+\r
+                        if (test.ok(userPerm)) {\r
+                            passed++;\r
+                            break;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            // All permissions must be OK\r
+            if (tested > 0 && tested == passed) {\r
+                return AuthorizationResult.Authorized;\r
+            } else {\r
+                return AuthorizationResult.AuthorizationFailure;\r
+            }\r
+        } catch (Exception e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+        return AuthorizationResult.AuthenticationFailure;\r
+    }\r
+\r
+    private Map<String, String> getUserPasssword(ContainerRequestContext requestContext) {\r
+\r
+        String header = requestContext.getHeaderString("Authorization");\r
+        Map<String, String> userPassword = getUserPasswordFromAuthorizationHeader(header);\r
+        // Add other stuff....\r
+        userPassword.put("path", requestContext.getUriInfo().getAbsolutePath().getPath());\r
+        userPassword.put("method", requestContext.getMethod());\r
+        Principal principal = requestContext.getSecurityContext().getUserPrincipal();\r
+        if (principal instanceof UsernamePasswordAuthenticationToken) {\r
+            UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) principal;\r
+            Object object = token.getDetails();\r
+            if (object instanceof WebAuthenticationDetails) {\r
+                WebAuthenticationDetails details = (WebAuthenticationDetails) object;\r
+                if (details.getSessionId() != null) {\r
+                    String sessionId = details.getRemoteAddress() + ":" + details.getSessionId();\r
+                    userPassword.put("sessionId", sessionId);\r
+                    userPassword.put("user", token.getName());\r
+                }\r
+\r
+            }\r
+        }\r
+        return userPassword;\r
+    }\r
+\r
+    private Map<String, String> getUserPasswordFromAuthorizationHeader(String header) {\r
+        Map<String, String> userPassword = new HashMap<>();\r
+        userPassword.put("user", "");\r
+        userPassword.put("password", "");\r
+        if (header != null) {\r
+            String[] auth = header.split("Basic ");\r
+            if (auth.length == 2) {\r
+                String token = getToken(auth[1]);\r
+                if (token.contains(":")) {\r
+                    String[] tokens = token.split(":");\r
+                    userPassword.put("user", tokens[0]);\r
+                    if (tokens.length == 2) {\r
+                        userPassword.put("password", tokens[1]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return userPassword;\r
+    }\r
+\r
+    private String getToken(String auth) {\r
+        try {\r
+            String token = new String(DatatypeConverter.parseBase64Binary(auth));\r
+            return token;\r
+        } catch (Exception e) {\r
+            return auth;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java
new file mode 100755 (executable)
index 0000000..a8d860d
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import java.io.IOException;\r
+import javax.annotation.Priority;\r
+import javax.ws.rs.WebApplicationException;\r
+import javax.ws.rs.container.ContainerRequestContext;\r
+import javax.ws.rs.container.ContainerRequestFilter;\r
+import javax.ws.rs.core.Response;\r
+import javax.ws.rs.core.Response.ResponseBuilder;\r
+import javax.ws.rs.ext.Provider;\r
+import org.onap.observations.Observation;\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.onap.optf.cmso.aaf.AafClientCache.AuthorizationResult;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.stereotype.Component;\r
+\r
+@Priority(1)\r
+@Provider\r
+@Component\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class AafContainerFilters implements ContainerRequestFilter {\r
+\r
+    @Autowired\r
+    AafClientCache aafClientCache;\r
+\r
+    @Override\r
+    public void filter(ContainerRequestContext requestContext) throws IOException {\r
+        ResponseBuilder builder = null;\r
+        AuthorizationResult status = null;\r
+        try {\r
+            status = aafClientCache.authorize(requestContext);\r
+        } catch (Exception e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            status = AuthorizationResult.AuthenticationFailure;\r
+        }\r
+        switch (status) {\r
+            case AuthenticationFailure:\r
+                builder = Response.status(Response.Status.UNAUTHORIZED).entity("");\r
+                builder.header("WWW-Authenticate", "Basic realm=\"Realm\"");\r
+                throw new WebApplicationException(builder.build());\r
+            case AuthorizationFailure:\r
+                builder = Response.status(Response.Status.FORBIDDEN).entity("");\r
+                throw new WebApplicationException(builder.build());\r
+            case Authorized:\r
+            case Authenticated:\r
+            default:\r
+        }\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafEndpoints.java
new file mode 100755 (executable)
index 0000000..e9c9181
--- /dev/null
@@ -0,0 +1,74 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Component;\r
+\r
+/**\r
+ * Intent is to use AAF vanity URL however, this allows us to support a list of URLs.\r
+ *\r
+ */\r
+@Component\r
+public class AafEndpoints extends BaseEndpoints {\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    public enum Endpoint implements EndpointInterface {\r
+        AUTHZ(AafProperties.aafAuthzPath, "/authz/perms/user/"), HEALTHCHECK(AafProperties.aafHealthCheckPath, "/"),;\r
+\r
+        private final AafProperties pathName;\r
+        private final String defaultPath;\r
+\r
+        private Endpoint(AafProperties pathname, String defaultPath) {\r
+            this.pathName = pathname;\r
+            this.defaultPath = defaultPath;\r
+        }\r
+\r
+        @Override\r
+        public AafProperties getPathName() {\r
+            return pathName;\r
+        }\r
+\r
+        @Override\r
+        public String defaultPath() {\r
+            return defaultPath;\r
+        }\r
+\r
+        @Override\r
+        public EndpointInterface[] getValues() {\r
+            return Endpoint.values();\r
+        }\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafFilter.java
deleted file mode 100644 (file)
index 661510d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import java.io.IOException;
-import java.util.Properties;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.onap.aaf.cadi.PropAccess;
-import org.onap.aaf.cadi.filter.CadiFilter;
-import org.onap.observations.Observation;
-import org.onap.optf.cmso.Application;
-import org.onap.optf.cmso.SpringProfiles;
-import org.onap.optf.cmso.common.LogMessages;
-import org.onap.optf.cmso.common.exceptions.CmsoException;
-import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-
-/**
- * AAF authentication filter.
- */
-
-@Component
-@Profile(SpringProfiles.AAF_AUTHENTICATION)
-public class AafFilter extends OrderedRequestContextFilter {
-
-    private final CadiFilter cadiFilter;
-
-    /**
-     * Instantiates a new aaf filter.
-     *
-     * @throws IOException Signals that an I/O exception has occurred.
-     * @throws ServletException the servlet exception
-     */
-    public AafFilter() throws IOException, ServletException {
-        Properties cadiProperties = new Properties();
-        cadiProperties.load(Application.class.getClassLoader().getResourceAsStream("cadi.properties"));
-        cadiFilter = new CadiFilter(new PropAccess(cadiProperties));
-        this.setOrder(FilterPriority.AAF_AUTHENTICATION.getPriority());
-    }
-
-    @Override
-    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
-                    throws IOException, ServletException {
-        cadiFilter.doFilter(request, response, filterChain);
-        if (response.getStatus() == 401) {
-            Observation.report(LogMessages.UNAUTHENTICATED);
-            ResponseFormatter.errorResponse(request, response,
-                            new CmsoException(LogMessages.UNAUTHENTICATED.getStatus(),
-                                            LogMessages.UNAUTHENTICATED, ""));
-        }
-    }
-
-
-}
old mode 100644 (file)
new mode 100755 (executable)
index 278f3ab..d324f18
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed under the Creative
- * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import java.util.HashSet;
-import java.util.Set;
-import org.onap.aaf.cadi.aaf.AAFPermission;
-
-
-/**
- * The Class AafPerm.
- */
-public class AafPerm {
-    private String type;
-    private String instance;
-    private String action;
-    private Set<String> actions = new HashSet<>();
-
-    /**
-     * Gets the action.
-     *
-     * @return the action
-     */
-    public String getAction() {
-        return action;
-    }
-
-    /**
-     * Sets the action.
-     *
-     * @param action the new action
-     */
-    public void setAction(String action) {
-        this.action = action;
-        String[] list = action.split(",");
-        for (String a : list) {
-            actions.add(a);
-        }
-    }
-
-    /**
-     * Gets the type.
-     *
-     * @return the type
-     */
-    public String getType() {
-        return type;
-    }
-
-    /**
-     * Sets the type.
-     *
-     * @param type the new type
-     */
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    /**
-     * Gets the single instance of AafPerm.
-     *
-     * @return single instance of AafPerm
-     */
-    public String getInstance() {
-        return instance;
-    }
-
-    /**
-     * Sets the instance.
-     *
-     * @param instance the new instance
-     */
-    public void setInstance(String instance) {
-        this.instance = instance;
-    }
-
-    /**
-     * Gets the actions.
-     *
-     * @return the actions
-     */
-    public Set<String> getActions() {
-        return actions;
-    }
-
-    /**
-     * Sets the actions.
-     *
-     * @param actions the new actions
-     */
-    public void setActions(Set<String> actions) {
-        this.actions = actions;
-    }
-
-    /**
-     * Matches.
-     *
-     * @param userPerm the user perm
-     * @return true, if successful
-     */
-    public boolean matches(AAFPermission userPerm) {
-        if (type.equals(userPerm.getType())) {
-            if (userPerm.getInstance().equals("*") || instance.equals("*") || userPerm.getInstance().equals(instance)) {
-                for (String userAction : userPerm.getAction().split(",")) {
-                    if (userAction.equals("*") || actions.contains("*") || actions.contains(userAction)) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-}
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+\r
+public class AafPerm {\r
+    private String type;\r
+    private String instance;\r
+    private String action;\r
+    private Set<String> actions = new HashSet<>();\r
+\r
+    public String getAction() {\r
+        return action;\r
+    }\r
+\r
+    /**\r
+     * Initialize the actions.\r
+     *\r
+     * @param action action list\r
+     */\r
+    public void setAction(String action) {\r
+        this.action = action;\r
+        String[] list = action.split(",");\r
+        for (String a : list) {\r
+            actions.add(a);\r
+        }\r
+    }\r
+\r
+    public String getType() {\r
+        return type;\r
+    }\r
+\r
+    public void setType(String type) {\r
+        this.type = type;\r
+    }\r
+\r
+    public String getInstance() {\r
+        return instance;\r
+    }\r
+\r
+    public void setInstance(String instance) {\r
+        this.instance = instance;\r
+    }\r
+\r
+    public Set<String> getActions() {\r
+        return actions;\r
+    }\r
+\r
+    public void setActions(Set<String> actions) {\r
+        this.actions = actions;\r
+    }\r
+\r
+    /**\r
+     * Are permissions ok.\r
+     *\r
+     * @param userPerm user permissions\r
+     * @return true = permissions ok\r
+     */\r
+    public boolean ok(AafPerm userPerm) {\r
+        if (type.equals(userPerm.getType())) {\r
+            if (userPerm.getInstance().equals("*") || instance.equals("*") || userPerm.getInstance().equals(instance)) {\r
+                for (String userAction : userPerm.getActions()) {\r
+                    if (userAction.equals("*") || actions.contains("*") || actions.contains(userAction)) {\r
+                        return true;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
similarity index 73%
rename from cmso-service/src/main/java/org/onap/optf/cmso/aaf/FilterPriority.java
rename to cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafPermResponse.java
index e861f71..caf2b62
@@ -1,46 +1,46 @@
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import org.springframework.core.Ordered;
-
-public enum FilterPriority {
-    AAF_AUTHENTICATION(Ordered.HIGHEST_PRECEDENCE), AAF_AUTHORIZATION(Ordered.HIGHEST_PRECEDENCE + 1);
-    private final int priority;
-
-    FilterPriority(final int ppri) {
-        priority = ppri;
-    }
-
-    public int getPriority() {
-        return priority;
-    }
-}
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import java.util.List;\r
+\r
+public class AafPermResponse {\r
+    private List<AafPerm> perm;\r
+\r
+    public List<AafPerm> getPerm() {\r
+        return perm;\r
+    }\r
+\r
+    public void setPerm(List<AafPerm> list) {\r
+        this.perm = list;\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafProperties.java
new file mode 100755 (executable)
index 0000000..00758e5
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+public enum AafProperties {\r
+    mechidUser("mechid.user"), mechidPass("mechid.pass"), aafUrls("aaf.urls"), aafAuthzPath(\r
+                    "aaf.path.authz"), aafHealthCheckPath("aaf.path.healthcheck"), aafCacheTimeout(\r
+                                    "aaf.cache.timeout"), aafUserRoleProperties(\r
+                                                    "aaf.user.role.properties"), aafDefaultUserDomain(\r
+                                                                    "aaf.default.user.domain"), aafEnabled(\r
+                                                                                    "aaf.enabled"), aafNamespace(\r
+                                                                                                    "aaf.namespace"),;\r
+    private final String text;\r
+\r
+    private AafProperties(String text) {\r
+        this.text = text;\r
+    }\r
+\r
+    @Override\r
+    public String toString() {\r
+        return text;\r
+    }\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
index 87938d7..806a7b1
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed under the Creative
- * Commons License, Attribution 4.0 Intl. (the "License"); you may not use this documentation except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * The Class AafUserRole.
- */
-public class AafUserRole {
-    private String url = "";
-    private String[] pathParts = {};
-    private String perm = "";
-    private String method = "";
-    private List<AafPerm> aafPerms = new ArrayList<>();
-
-    /**
-     * Instantiates a new aaf user role.
-     *
-     * @param url the url
-     * @param perm the perm
-     */
-    public AafUserRole(String url, String perm) {
-        this.setUrl(url);
-        this.setPerm(perm);
-        pathParts = url.split("\\/");
-
-        String[] perms = perm.split(",");
-        for (String p : perms) {
-            String[] parts = p.split(" ");
-            if (parts.length == 2) {
-                method = parts[1];
-            }
-            else {
-                method = "ALL";
-            }
-
-            String[] list = parts[0].split("\\|");
-            if (list.length == 3) {
-                AafPerm aafPerm = new AafPerm();
-                aafPerm.setAction(list[2]);
-                aafPerm.setInstance(list[1]);
-                aafPerm.setType(list[0]);
-                aafPerms.add(aafPerm);
-            }
-        }
-    }
-
-    /**
-     * Gets the url.
-     *
-     * @return the url
-     */
-    public String getUrl() {
-        return url;
-    }
-
-    /**
-     * Sets the url.
-     *
-     * @param url the new url
-     */
-    public void setUrl(String url) {
-        this.url = url;
-    }
-
-    /**
-     * Gets the perm.
-     *
-     * @return the perm
-     */
-    public String getPerm() {
-        return perm;
-    }
-
-    /**
-     * Sets the perm.
-     *
-     * @param perm the new perm
-     */
-    public void setPerm(String perm) {
-        this.perm = perm;
-    }
-
-    /**
-     * Gets the aaf perms.
-     *
-     * @return the aaf perms
-     */
-    public List<AafPerm> getAafPerms() {
-        return aafPerms;
-    }
-
-    /**
-     * Sets the aaf perms.
-     *
-     * @param aafPerms the new aaf perms
-     */
-    public void setAafPerms(List<AafPerm> aafPerms) {
-        this.aafPerms = aafPerms;
-    }
-
-    /**
-     * Matches.
-     *
-     * @param path the path
-     * @param matchMethod the match method
-     * @return true, if successful
-     */
-    public boolean matches(String path, String matchMethod) {
-        if (!this.method.equalsIgnoreCase("ALL") && !this.method.equals("*") && !this.method.equals(matchMethod)) {
-            return false;
-        }
-        List<String> inNodes = new ArrayList<>();
-        List<String> matchNodes = new ArrayList<>();
-        String[] pathList = path.split("\\/");
-        for (String n : pathList) {
-            inNodes.add(n);
-        }
-        for (String n : pathParts) {
-            matchNodes.add(n);
-        }
-
-        while (!inNodes.isEmpty() && !matchNodes.isEmpty()) {
-            String inNode = inNodes.remove(0);
-            String matchNode = matchNodes.get(0);
-            if (matchNode.equals(inNode) || matchNode.equals("*")) {
-                matchNodes.remove(0);
-            } else {
-                if (!matchNode.equals("**")) {
-                    return false;
-                }
-            }
-        }
-
-        //
-        if (inNodes.isEmpty() && matchNodes.isEmpty()) {
-            return true;
-        }
-
-        // We have incoming nodes remaining, see if we can wildcard them
-        if (matchNodes.size() == 1) {
-            if (matchNodes.get(0).equals("**")) {
-                return true;
-            }
-            if (inNodes.size() == 1 && matchNodes.get(0).equals("*")) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import com.fasterxml.jackson.core.JsonProcessingException;\r
+import com.fasterxml.jackson.databind.ObjectMapper;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import org.onap.observations.Observation;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+\r
+/**\r
+ * The Class AafUserRole.\r
+ */\r
+public class AafUserRole {\r
+    private String url = "";\r
+    private String[] pathParts = {};\r
+    private String perm = "";\r
+    private String method = "";\r
+    private List<AafPerm> aafPerms = new ArrayList<>();\r
+\r
+    /**\r
+     * Instantiates a new aaf user role.\r
+     *\r
+     * @param url the url\r
+     * @param perm the perm\r
+     */\r
+    public AafUserRole(String url, String perm) {\r
+        this.setUrl(url);\r
+        this.setPerm(perm);\r
+        pathParts = url.split("\\/");\r
+\r
+        String[] perms = perm.split(",");\r
+        for (String p : perms) {\r
+            String[] parts = p.split(" ");\r
+            if (parts.length == 2) {\r
+                method = parts[1];\r
+            }\r
+            else {\r
+                method = "ALL";\r
+            }\r
+\r
+            String[] list = parts[0].split("\\|");\r
+            if (list.length == 3) {\r
+                AafPerm aafPerm = new AafPerm();\r
+                aafPerm.setAction(list[2]);\r
+                aafPerm.setInstance(list[1]);\r
+                aafPerm.setType(list[0]);\r
+                aafPerms.add(aafPerm);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Gets the url.\r
+     *\r
+     * @return the url\r
+     */\r
+    public String getUrl() {\r
+        return url;\r
+    }\r
+\r
+    /**\r
+     * Sets the url.\r
+     *\r
+     * @param url the new url\r
+     */\r
+    public void setUrl(String url) {\r
+        this.url = url;\r
+    }\r
+\r
+    /**\r
+     * Gets the perm.\r
+     *\r
+     * @return the perm\r
+     */\r
+    public String getPerm() {\r
+        return perm;\r
+    }\r
+\r
+    /**\r
+     * Sets the perm.\r
+     *\r
+     * @param perm the new perm\r
+     */\r
+    public void setPerm(String perm) {\r
+        this.perm = perm;\r
+    }\r
+\r
+    /**\r
+     * Gets the aaf perms.\r
+     *\r
+     * @return the aaf perms\r
+     */\r
+    public List<AafPerm> getAafPerms() {\r
+        return aafPerms;\r
+    }\r
+\r
+    /**\r
+     * Sets the aaf perms.\r
+     *\r
+     * @param aafPerms the new aaf perms\r
+     */\r
+    public void setAafPerms(List<AafPerm> aafPerms) {\r
+        this.aafPerms = aafPerms;\r
+    }\r
+\r
+    /**\r
+     * Matches.\r
+     *\r
+     * @param path the path\r
+     * @param matchMethod the match method\r
+     * @return true, if successful\r
+     */\r
+    public boolean matches(String path, String matchMethod) {\r
+        if (!this.method.equals("ALL") && !this.method.equals(matchMethod)) {\r
+            return false;\r
+        }\r
+        List<String> inNodes = new ArrayList<>();\r
+        List<String> matchNodes = new ArrayList<>();\r
+        String[] pathList = path.split("\\/");\r
+        for (String n : pathList) {\r
+            inNodes.add(n);\r
+        }\r
+        for (String n : pathParts) {\r
+            matchNodes.add(n);\r
+        }\r
+\r
+        while (!inNodes.isEmpty() && !matchNodes.isEmpty()) {\r
+            String inNode = inNodes.remove(0);\r
+            String matchNode = matchNodes.get(0);\r
+            if (matchNode.equals(inNode) || matchNode.equals("*")) {\r
+                matchNodes.remove(0);\r
+            } else {\r
+                if (!matchNode.equals("**")) {\r
+                    return false;\r
+                }\r
+            }\r
+        }\r
+\r
+        //\r
+        if (inNodes.isEmpty() && matchNodes.isEmpty()) {\r
+            return true;\r
+        }\r
+\r
+        // We have incoming nodes remaining, see if we can wildcard them\r
+        if (matchNodes.size() == 1) {\r
+            if (matchNodes.get(0).equals("**")) {\r
+                return true;\r
+            }\r
+            if (inNodes.size() == 1 && matchNodes.get(0).equals("*")) {\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see java.lang.Object#toString()\r
+     */\r
+    @Override\r
+    public String toString() {\r
+        try {\r
+            return new ObjectMapper().writeValueAsString(this);\r
+        } catch (JsonProcessingException e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.toString());\r
+        }\r
+        return this.url;\r
+    }\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
index 624171d..26bb436
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.File;
-import java.io.FileInputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import javax.annotation.PostConstruct;
-import javax.servlet.http.HttpServletRequest;
-import org.onap.aaf.cadi.Permission;
-import org.onap.aaf.cadi.aaf.AAFPermission;
-import org.onap.observations.Observation;
-import org.onap.optf.cmso.SpringProfiles;
-import org.onap.optf.cmso.common.LogMessages;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Profile;
-import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Component;
-
-/**
- * This class uses a properties file to map URL patterns/method to AAF Permissions (AafPerm).
- *
- * @author jf9860
- *
- */
-@Component
-@Profile(SpringProfiles.AAF_AUTHENTICATION)
-public class AafUserRoleProperties {
-    @Autowired
-    Environment env;
-
-    private List<AafUserRole> list = new ArrayList<>();
-
-    /**
-     * Initialize permissions.
-     */
-    @PostConstruct
-    public void initializePermissions() {
-        String userRolePropertiesName =
-                        env.getProperty("aaf.user.roles", "src/main/resources/aaf/AAFUserRoles.properties");
-        Properties props = new Properties();
-        try {
-            props.load(new FileInputStream(new File(userRolePropertiesName)));
-        } catch (Exception e) {
-            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
-        }
-        for (Object url : props.keySet()) {
-            Object value = props.get(url);
-            list.add(new AafUserRole((String) url, (String) value));
-        }
-    }
-
-    /**
-     * Gets the for url method.
-     *
-     * @param url the url
-     * @param method the method
-     * @return the for url method
-     */
-    public List<AafUserRole> getForUrlMethod(String url, String method) {
-        List<AafUserRole> userRoleList = new ArrayList<>();
-        for (AafUserRole aur : list) {
-            if (aur.matches(url, method)) {
-                userRoleList.add(aur);
-            }
-        }
-        return userRoleList;
-    }
-
-    /**
-     * Process permissions.
-     *
-     * @param request the request
-     * @param userPerms the user perms
-     * @return true, if successful
-     */
-    public boolean processPermissions(HttpServletRequest request, List<Permission> userPerms) {
-        try {
-            // Get list of perms that match incoming URL. May be more than 1...
-            // Users perms must match all that match URL
-            List<AafUserRole> perms = getForUrlMethod(request.getRequestURI(), request.getMethod());
-            int tested = 0;
-            int passed = 0;
-            for (AafUserRole perm : perms) {
-                for (AafPerm test : perm.getAafPerms()) {
-                    tested++;
-                    for (Permission userPerm : userPerms) {
-
-                        if (test.matches((AAFPermission) userPerm)) {
-                            passed++;
-                            break;
-                        }
-                    }
-                }
-            }
-            // All permissions must be OK
-            if (tested > 0 && tested == passed) {
-                return true;
-            }
-            else {
-                return false;
-            }
-        } catch (Exception e) {
-            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
-        }
-        return false;
-    }
-}
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import com.att.eelf.configuration.EELFLogger;\r
+import com.att.eelf.configuration.EELFManager;\r
+import java.nio.file.Files;\r
+import java.nio.file.Paths;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+import javax.annotation.PostConstruct;\r
+import org.onap.observations.Observation;\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.onap.optf.cmso.common.LogMessages;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Component;\r
+\r
+/**\r
+ * The Class AafUserRoleProperties.\r
+ */\r
+@Component\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class AafUserRoleProperties {\r
+    private static EELFLogger debug = EELFManager.getInstance().getDebugLogger();\r
+\r
+    /** The env. */\r
+    @Autowired\r
+    Environment env;\r
+\r
+    private List<AafUserRole> list = new ArrayList<>();\r
+\r
+    /**\r
+     * Initialize permissions.\r
+     */\r
+    @PostConstruct\r
+    public void initializePermissions() {\r
+        String userRolePropertiesName = env.getProperty(AafProperties.aafUserRoleProperties.toString(),\r
+                        "opt/att/ajsc/config/AAFUserRoles.properties");\r
+        try {\r
+            List<String> lines = Files.readAllLines(Paths.get(userRolePropertiesName));\r
+            for (String line : lines) {\r
+                line = line.trim();\r
+                if (!line.startsWith("#")) {\r
+                    String[] parts = line.split("=");\r
+                    if (parts.length == 2) {\r
+                        list.add(new AafUserRole(parts[0], env.resolvePlaceholders(parts[1])));\r
+                    } else {\r
+                        Observation.report(LogMessages.INVALID_ATTRIBUTE, line, userRolePropertiesName);\r
+                    }\r
+                }\r
+            }\r
+        } catch (Exception e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+        }\r
+        debug.debug("AafUserRole.properties: " + list);\r
+    }\r
+\r
+    /**\r
+     * Gets the for url method.\r
+     *\r
+     * @param url the url\r
+     * @param method the method\r
+     * @return the for url method\r
+     */\r
+    public List<AafUserRole> getForUrlMethod(String url, String method) {\r
+        List<AafUserRole> userRoleList = new ArrayList<>();\r
+        for (AafUserRole aur : list) {\r
+            if (aur.matches(url, method)) {\r
+                userRoleList.add(aur);\r
+            }\r
+        }\r
+        return userRoleList;\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/BaseEndpoints.java
new file mode 100755 (executable)
index 0000000..1027ade
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import java.util.ArrayList;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.core.env.Environment;\r
+import org.springframework.stereotype.Component;\r
+\r
+/**\r
+ * Intent is to use AAF vanity URL however, this allows us to support a list of URLs.\r
+ */\r
+@Component\r
+public class BaseEndpoints {\r
+\r
+    @Autowired\r
+    Environment env;\r
+\r
+    private Map<EndpointInterface, List<String>> endpointMap = new HashMap<>();\r
+    private Map<EndpointInterface, String> endpointMapOk = new HashMap<>();\r
+\r
+    /**\r
+     * Gets the endpoint.\r
+     *\r
+     * @param ep the ep\r
+     * @param endpoints the endpoints\r
+     * @return the endpoint\r
+     */\r
+    public String getEndpoint(EndpointInterface ep, List<String> endpoints) {\r
+        loadUrls(ep);\r
+        endpoints.clear();\r
+        endpoints.addAll(endpointMap.get(ep));\r
+        String endpoint = null;\r
+        if (endpoints.size() > 0) {\r
+            // Make an attempt to return the most recent "working" endpoint.\r
+            //\r
+            synchronized (endpointMapOk) {\r
+                endpoint = endpointMapOk.get(ep);\r
+                if (endpoint == null) {\r
+                    endpoint = endpoints.get(0);\r
+                    endpointMapOk.put(ep, endpoint);\r
+                }\r
+            }\r
+            endpoints.remove(endpoint);\r
+        }\r
+        return endpoint;\r
+    }\r
+\r
+    // Call this if the previous enpoint failed to connect.\r
+    /**\r
+     * Gets the next endpoint.\r
+     *\r
+     * @param ep the ep\r
+     * @param endpoints the endpoints\r
+     * @return the next endpoint\r
+     */\r
+    // An attempt to track the most recent "working" endpoint.\r
+    public String getNextEndpoint(EndpointInterface ep, List<String> endpoints) {\r
+        String endpoint = null;\r
+        if (endpoints.size() > 0) {\r
+            endpoint = endpoints.remove(0);\r
+            synchronized (endpointMapOk) {\r
+                // Let's hope this one works.\r
+                endpointMapOk.put(ep, endpoint);\r
+            }\r
+        }\r
+        return endpoint;\r
+    }\r
+\r
+    private synchronized void loadUrls(EndpointInterface endpoint) {\r
+        endpointMap = new HashMap<>();\r
+        String urls = env.getProperty(AafProperties.aafUrls.toString());\r
+        String[] list = urls.split("\\|");\r
+        for (String url : list) {\r
+            for (EndpointInterface ep : endpoint.getValues()) {\r
+                addToEndpointMap(ep, url);\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    private void addToEndpointMap(EndpointInterface ep, String endpoint) {\r
+        List<String> list = endpointMap.get(ep);\r
+        if (list == null) {\r
+            list = new ArrayList<>();\r
+            endpointMap.put(ep, list);\r
+        }\r
+        String path = env.getProperty(ep.getPathName().toString(), ep.defaultPath());\r
+        list.add(endpoint + path);\r
+    }\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
similarity index 64%
rename from cmso-service/src/main/java/org/onap/optf/cmso/aaf/ResponseFormatter.java
rename to cmso-service/src/main/java/org/onap/optf/cmso/aaf/EndpointInterface.java
index 8ed6df3..af0039d
@@ -1,49 +1,41 @@
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- ******************************************************************************/
-
-package org.onap.optf.cmso.aaf;
-
-import java.io.IOException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.onap.optf.cmso.common.exceptions.CmsoException;
-
-class ResponseFormatter {
-
-
-    static void errorResponse(HttpServletRequest request, HttpServletResponse response, CmsoException error)
-                    throws IOException {
-        response.setStatus(error.getStatus().getStatusCode());
-        response.getWriter().write(error.getRequestError().toString());
-        response.getWriter().flush();
-        response.getWriter().close();
-    }
-
-}
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+public interface EndpointInterface {\r
+    public AafProperties getPathName();\r
+\r
+    public String defaultPath();\r
+\r
+    public EndpointInterface[] getValues();\r
+\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
similarity index 79%
rename from cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafSecurityConfig.java
rename to cmso-service/src/main/java/org/onap/optf/cmso/aaf/SecurityConfig.java
index 068e6c3..80eea75
@@ -1,60 +1,65 @@
-/*
- * Copyright © 2019 AT&T Intellectual Property.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *
- * Unless otherwise specified, all documentation contained herein is licensed
- * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
- * you may not use this documentation except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *         https://creativecommons.org/licenses/by/4.0/
- *
- * Unless required by applicable law or agreed to in writing, documentation
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-package org.onap.optf.cmso.aaf;
-
-import org.onap.optf.cmso.SpringProfiles;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-
-@Configuration
-@EnableWebSecurity
-@ComponentScan("org.onap.optf")
-@Profile(SpringProfiles.AAF_AUTHENTICATION)
-public class AafSecurityConfig extends WebSecurityConfigurerAdapter {
-
-
-    @Override
-    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-
-    }
-
-    @Override
-    protected void configure(HttpSecurity http) throws Exception {
-
-        http.csrf().disable();
-
-    }
-}
\ No newline at end of file
+/*\r
+ * Copyright (c) 2019 AT&T Intellectual Property.\r
+ * Modifications Copyright © 2018 IBM.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ *\r
+ * Unless otherwise specified, all documentation contained herein is licensed\r
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");\r
+ * you may not use this documentation except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *         https://creativecommons.org/licenses/by/4.0/\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, documentation\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+*/\r
+\r
+package org.onap.optf.cmso.aaf;\r
+\r
+import org.onap.optf.cmso.SpringProfiles;\r
+import org.springframework.beans.factory.annotation.Autowired;\r
+import org.springframework.context.annotation.ComponentScan;\r
+import org.springframework.context.annotation.Configuration;\r
+import org.springframework.context.annotation.Profile;\r
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;\r
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;\r
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;\r
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;\r
+\r
+@Configuration\r
+@EnableWebSecurity\r
+@ComponentScan("org.onap")\r
+@Profile(SpringProfiles.AAF_AUTHENTICATION)\r
+public class SecurityConfig extends WebSecurityConfigurerAdapter {\r
+\r
+    @Autowired\r
+    private AafAuthProvider authProvider;\r
+\r
+    @Override\r
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {\r
+        auth.authenticationProvider(authProvider);\r
+\r
+    }\r
+\r
+    @Override\r
+    protected void configure(HttpSecurity http) throws Exception {\r
+\r
+        http.csrf().disable().authorizeRequests().anyRequest().authenticated().and().httpBasic().realmName("Realm");\r
+\r
+    }\r
+}\r
diff --git a/cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json b/cmso-service/src/main/resources/META-INF/resources/swagger/swagger.json
new file mode 100644 (file)
index 0000000..f987661
--- /dev/null
@@ -0,0 +1,1234 @@
+{
+  "swagger" : "2.0",
+  "info" : {
+    "version" : "2.1.1-SNAPSHOT",
+    "title" : "cmso-service"
+  },
+  "basePath" : "/cmso",
+  "tags" : [ {
+    "name" : "CMSO Administration"
+  }, {
+    "name" : "CMSO Optimized Schedule API"
+  }, {
+    "name" : "CMSO Schedule API"
+  } ],
+  "paths" : {
+    "/{apiVersion}/admin/{id}" : {
+      "get" : {
+        "tags" : [ "CMSO Administration" ],
+        "summary" : "",
+        "description" : "Returns encrypted value of id.",
+        "operationId" : "exec",
+        "produces" : [ "text/plain" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1|v2",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "id",
+          "in" : "path",
+          "description" : "Identifier",
+          "required" : true,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "csv"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK",
+            "schema" : {
+              "type" : "string"
+            }
+          },
+          "400" : {
+            "description" : "Request failed"
+          }
+        }
+      }
+    },
+    "/{apiVersion}/health" : {
+      "get" : {
+        "tags" : [ "CMSO Administration" ],
+        "summary" : "",
+        "description" : "Returns health status of server.",
+        "operationId" : "healthCheck",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "checkInterfaces",
+          "in" : "query",
+          "description" : "Check Interfaces",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "boolean",
+            "default" : true
+          },
+          "collectionFormat" : "multi"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK",
+            "schema" : {
+              "$ref" : "#/definitions/HealthCheckMessage"
+            }
+          },
+          "400" : {
+            "description" : "Not healthy",
+            "schema" : {
+              "$ref" : "#/definitions/HealthCheckMessage"
+            }
+          }
+        }
+      }
+    },
+    "/{apiVersion}/schedules" : {
+      "get" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Returns a list of Scheduler Requests based upon the filter criteria.",
+        "operationId" : "searchScheduleRequests",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "includeDetails",
+          "in" : "query",
+          "description" : "Include details",
+          "required" : false,
+          "type" : "boolean",
+          "default" : false
+        }, {
+          "name" : "scheduleId",
+          "in" : "query",
+          "description" : "Schedule identifier",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "scheduleName",
+          "in" : "query",
+          "description" : "Schedule name",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "userId",
+          "in" : "query",
+          "description" : "SCheduler creator User id of ",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "status",
+          "in" : "query",
+          "description" : "Schedule status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "createDateTime",
+          "in" : "query",
+          "description" : "Creation date and time (<low date>[,<hi date>])",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "optimizerStatus",
+          "in" : "query",
+          "description" : "Optimizer status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "WorkflowName",
+          "in" : "query",
+          "description" : "Workflow",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK",
+            "schema" : {
+              "type" : "array",
+              "items" : {
+                "$ref" : "#/definitions/Schedule"
+              }
+            }
+          },
+          "404" : {
+            "description" : "No records found",
+            "schema" : {
+              "$ref" : "#/definitions/CmsoRequestError"
+            }
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      }
+    },
+    "/{apiVersion}/schedules/optimized/{scheduleId}" : {
+      "post" : {
+        "tags" : [ "CMSO Optimized Schedule API" ],
+        "summary" : "",
+        "description" : "Creates a request for an optimized schedule",
+        "operationId" : "createScheduleRequest",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "scheduleId",
+          "in" : "path",
+          "description" : "Schedule id to uniquely identify the schedule request being created.",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "in" : "body",
+          "name" : "body",
+          "description" : "Data for creating a schedule request for the given schedule id",
+          "required" : false,
+          "schema" : {
+            "$ref" : "#/definitions/Optimized Schedule Request"
+          }
+        } ],
+        "responses" : {
+          "202" : {
+            "description" : "Schedule request accepted for optimization."
+          },
+          "409" : {
+            "description" : "Schedule request already exists for this schedule id.",
+            "schema" : {
+              "$ref" : "#/definitions/CmsoRequestError"
+            }
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      }
+    },
+    "/{apiVersion}/schedules/scheduleDetails" : {
+      "get" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Returns a list of Schedule request details based upon the filter criteria.",
+        "operationId" : "searchScheduleRequestDetails",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "request.scheduleId",
+          "in" : "query",
+          "description" : "Schedule identifier",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.scheduleName",
+          "in" : "query",
+          "description" : "Schedule name",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.userId",
+          "in" : "query",
+          "description" : "Scheduler creator User id of ",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.status",
+          "in" : "query",
+          "description" : "Schedule status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.createDateTime",
+          "in" : "query",
+          "description" : "Creation date and time (<low date>[,<hi date>])",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.optimizerStatus",
+          "in" : "query",
+          "description" : "Optimizer status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.approvalUserId",
+          "in" : "query",
+          "description" : "Request Approval user id",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.approvalStatus",
+          "in" : "query",
+          "description" : "Request Approval status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "request.approvalType",
+          "in" : "query",
+          "description" : "Request Approval type",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "WorkflowName",
+          "in" : "query",
+          "description" : "Workflow",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "vnfName",
+          "in" : "query",
+          "description" : "VNF Name",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "vnfId",
+          "in" : "query",
+          "description" : "VNF Id",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "vnfStatus",
+          "in" : "query",
+          "description" : "VNF Status",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "startTime",
+          "in" : "query",
+          "description" : "Start time <low>,<high>",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "finishTime",
+          "in" : "query",
+          "description" : "Finish time <low>,<high>",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "lastInstanceTime",
+          "in" : "query",
+          "description" : "Last instance start time <low>,<high>",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "tmChangeId",
+          "in" : "query",
+          "description" : "TM Change Ticket Change Id",
+          "required" : false,
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          },
+          "collectionFormat" : "multi"
+        }, {
+          "name" : "maxSchedules",
+          "in" : "query",
+          "description" : "Maximum number of schedules to return",
+          "required" : false,
+          "type" : "integer",
+          "format" : "int32"
+        }, {
+          "name" : "lastScheduleId",
+          "in" : "query",
+          "description" : "Return schedules > lastScheduleId",
+          "required" : false,
+          "type" : "string"
+        }, {
+          "name" : "request.concurrencyLimit",
+          "in" : "query",
+          "description" : "Return concurrencyLimit",
+          "required" : false,
+          "type" : "integer",
+          "format" : "int32"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK",
+            "schema" : {
+              "type" : "array",
+              "items" : {
+                "$ref" : "#/definitions/CmDetailsMessage"
+              }
+            }
+          },
+          "404" : {
+            "description" : "No records found",
+            "schema" : {
+              "$ref" : "#/definitions/CmsoRequestError"
+            }
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      }
+    },
+    "/{apiVersion}/schedules/{scheduleId}" : {
+      "get" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Retrieve the schedule request for scheduleId",
+        "operationId" : "getScheduleRequestInfo",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "scheduleId",
+          "in" : "path",
+          "description" : "Schedule id to uniquely identify the schedule info being retrieved.",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK",
+            "schema" : {
+              "$ref" : "#/definitions/Schedule"
+            }
+          },
+          "404" : {
+            "description" : "No record found"
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      },
+      "post" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Creates a schedule request for scheduleId",
+        "operationId" : "createScheduleRequest",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "scheduleId",
+          "in" : "path",
+          "description" : "Schedule id to uniquely identify the schedule request being created.",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "in" : "body",
+          "name" : "body",
+          "description" : "Data for creating a schedule request for the given schedule id",
+          "required" : false,
+          "schema" : {
+            "$ref" : "#/definitions/CmsoMessage"
+          }
+        } ],
+        "responses" : {
+          "202" : {
+            "description" : "Schedule request accepted for optimization."
+          },
+          "409" : {
+            "description" : "Schedule request already exists for this schedule id.",
+            "schema" : {
+              "$ref" : "#/definitions/CmsoRequestError"
+            }
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      },
+      "delete" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Cancels the schedule request for scheduleId",
+        "operationId" : "deleteScheduleRequest",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "scheduleId",
+          "in" : "path",
+          "description" : "Schedule id to uniquely identify the schedule request being deleted.",
+          "required" : true,
+          "type" : "string"
+        } ],
+        "responses" : {
+          "204" : {
+            "description" : "Delete successful"
+          },
+          "404" : {
+            "description" : "No record found",
+            "schema" : {
+              "$ref" : "#/definitions/CmsoRequestError"
+            }
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      }
+    },
+    "/{apiVersion}/schedules/{scheduleId}/approvals" : {
+      "post" : {
+        "tags" : [ "CMSO Schedule API" ],
+        "summary" : "",
+        "description" : "Adds an accept/reject approval status to the schedule request identified by scheduleId",
+        "operationId" : "approveScheduleRequest",
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "apiVersion",
+          "in" : "path",
+          "description" : "v1",
+          "required" : true,
+          "type" : "string",
+          "default" : "v1"
+        }, {
+          "name" : "scheduleId",
+          "in" : "path",
+          "description" : "Schedule id to uniquely identify the schedule request being accepted or rejected.",
+          "required" : true,
+          "type" : "string"
+        }, {
+          "in" : "body",
+          "name" : "body",
+          "description" : "Accept or reject approval message",
+          "required" : false,
+          "schema" : {
+            "$ref" : "#/definitions/Schedule Approval Request"
+          }
+        } ],
+        "responses" : {
+          "200" : {
+            "description" : "OK"
+          },
+          "404" : {
+            "description" : "No record found"
+          },
+          "500" : {
+            "description" : "Unexpected Runtime error"
+          }
+        }
+      }
+    }
+  },
+  "definitions" : {
+    "Change Management Group" : {
+      "type" : "object",
+      "properties" : {
+        "finishTime" : {
+          "type" : "string",
+          "description" : "Date/time by which all of the workflows should be completed."
+        },
+        "groupId" : {
+          "type" : "string",
+          "description" : "Name of the group of VNFs to be scheduled"
+        },
+        "lastInstanceStartTime" : {
+          "type" : "string",
+          "description" : "The latest date/time by which a workflow is to be started."
+        },
+        "startTime" : {
+          "type" : "string",
+          "description" : "The date/time when workflows are to be started."
+        },
+        "additionalDurationInSecs" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "Time added to the workflow interval to allow for rollback in case of failure."
+        },
+        "concurrencyLimit" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "The maximum number of workflows that should be started simultaneiously."
+        },
+        "normalDurationInSecs" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "Expected duration of a successful workflow execution."
+        },
+        "policyId" : {
+          "type" : "string",
+          "description" : "The name of the schedule optimization policy used by the change management schedule optimizer."
+        },
+        "changeManagementSchedules" : {
+          "type" : "array",
+          "description" : "The list of VNF workflows scheduled.",
+          "items" : {
+            "$ref" : "#/definitions/Change Management Schedule"
+          }
+        }
+      },
+      "description" : "Scheduling critirea for a group of VNFs"
+    },
+    "Change Management Schedule" : {
+      "type" : "object",
+      "properties" : {
+        "tmChangeId" : {
+          "type" : "string",
+          "description" : "TM Change Id"
+        },
+        "tmStatus" : {
+          "type" : "string",
+          "description" : "TM ticket status",
+          "enum" : [ "<null>", "Closed" ]
+        },
+        "tmApprovalStatus" : {
+          "type" : "string",
+          "description" : "TM ticket approval status",
+          "enum" : [ "<null>", "Approved" ]
+        },
+        "finishTime" : {
+          "type" : "string",
+          "description" : "Anticipated time of completion based upon start time and duration"
+        },
+        "startTime" : {
+          "type" : "string",
+          "description" : "Start time of this VNF workflow assigned by Scheduler based upon the group start time returned by the optimizer and concurrency."
+        },
+        "status" : {
+          "type" : "string",
+          "description" : "Status of the VNF.",
+          "enum" : [ "See CMSStatusEnum" ]
+        },
+        "vnfName" : {
+          "type" : "string",
+          "description" : "Name of the VNF."
+        },
+        "dispatchTime" : {
+          "type" : "string",
+          "description" : "Actual time the VNF workflow was dispatched."
+        },
+        "executionCompletedTime" : {
+          "type" : "string",
+          "description" : "Actual time the VNF workflow execution was completed as reported by MSO."
+        },
+        "msoRequestId" : {
+          "type" : "string",
+          "description" : "MSO Request ID of the workflow returned at dispatch time."
+        },
+        "msoStatus" : {
+          "type" : "string",
+          "description" : "Final MSO status.",
+          "enum" : [ "COMPLETED", "FAILED" ]
+        },
+        "msoMessage" : {
+          "type" : "string",
+          "description" : "MSO final status message."
+        },
+        "statusMessage" : {
+          "type" : "string",
+          "description" : "Scheduler status message."
+        },
+        "msoTime" : {
+          "type" : "string",
+          "description" : "Time of last poll for MSO status."
+        },
+        "request" : {
+          "type" : "string",
+          "description" : "Change equest."
+        }
+      },
+      "description" : "VNF details for Change Management Schedule"
+    },
+    "Change Management Scheduling Info" : {
+      "type" : "object",
+      "properties" : {
+        "normalDurationInSeconds" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "Expected duration (in seconds) of a successful execution of a single VNF change."
+        },
+        "additionalDurationInSeconds" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "Additional duration (in seconds) to be added to support backout of an unsuccessful VNF change."
+        },
+        "concurrencyLimit" : {
+          "type" : "integer",
+          "format" : "int32",
+          "description" : "Maximum number of VNF changes to schedule concurrently"
+        },
+        "changeWindows" : {
+          "type" : "array",
+          "description" : "Lists of desired change windows to schedule the elements.",
+          "items" : {
+            "$ref" : "#/definitions/Change Window"
+          }
+        },
+        "policies" : {
+          "type" : "array",
+          "description" : "List of the policies to control optimization.",
+          "items" : {
+            "$ref" : "#/definitions/Supported Policy Information"
+          }
+        },
+        "elements" : {
+          "type" : "array",
+          "description" : "Lists of the VNFs to be changed and the desired change windows",
+          "items" : {
+            "$ref" : "#/definitions/Optimizer Element"
+          }
+        }
+      },
+      "description" : "Details of schedule being requested"
+    },
+    "Change Window" : {
+      "type" : "object",
+      "properties" : {
+        "startTime" : {
+          "type" : "string",
+          "format" : "date-time",
+          "description" : "Earliest time for which changes may begin."
+        },
+        "endTime" : {
+          "type" : "string",
+          "format" : "date-time",
+          "description" : "Latest time by which all changes must be completed."
+        }
+      },
+      "description" : "Time window for which tickets are to returned"
+    },
+    "CmDetailsMessage" : {
+      "type" : "object",
+      "properties" : {
+        "vnfName" : {
+          "type" : "string",
+          "description" : "Name of the VNF."
+        },
+        "status" : {
+          "type" : "string",
+          "description" : "Status of the VNF.",
+          "enum" : [ "See CMSStatusEnum" ]
+        },
+        "tmChangeId" : {
+          "type" : "string",
+          "description" : "TM Change Id"
+        },
+        "tmStatus" : {
+          "type" : "string",
+          "description" : "TM ticket status",
+          "enum" : [ "<null>", "Closed" ]
+        },
+        "tmApprovalStatus" : {
+          "type" : "string",
+          "description" : "TM ticket approval status",
+          "enum" : [ "<null>", "Approved" ]
+        },
+        "startTime" : {
+          "type" : "string",
+          "description" : "Start time of this VNF workflow assigned by Scheduler based upon the group start time returned by the optimizer and concurrency."
+        },
+        "finishTime" : {
+          "type" : "string",
+          "description" : "Anticipated time of completion based upon start time and duration"
+        },
+        "groupId" : {
+          "type" : "string",
+          "description" : "Name of the group of VNFs to be scheduled"
+        },
+        "lastInstanceStartTime" : {
+          "type" : "string",
+          "description" : "The latest date/time by which a workflow is to be started."
+        },
+        "policyId" : {
+          "type" : "string",
+          "description" : "Time of last poll for MSO status."
+        },
+        "dispatchTime" : {
+          "type" : "string",
+          "description" : "Actual time the VNF workflow was dispatched."
+        },
+        "executionCompletedTime" : {
+          "type" : "string",
+          "description" : "Actual time the VNF workflow execution was completed as reported by MSO."
+        },
+        "msoRequestId" : {
+          "type" : "string",
+          "description" : "MSO Request ID of the workflow returned at dispatch time."
+        },
+        "msoStatus" : {
+          "type" : "string",
+          "description" : "Final MSO status.",
+          "enum" : [ "COMPLETED", "FAILED" ]
+        },
+        "msoMessage" : {
+          "type" : "string",
+          "description" : "MSO final status message."
+        },
+        "statusMessage" : {
+          "type" : "string",
+          "description" : "Scheduler status message."
+        },
+        "msoTime" : {
+          "type" : "string",
+          "description" : "Time of last poll for MSO status."
+        },
+        "scheduleRequest" : {
+          "$ref" : "#/definitions/Schedule"
+        },
+        "approvals" : {
+          "type" : "array",
+          "items" : {
+            "$ref" : "#/definitions/Schedule Approval Request"
+          }
+        }
+      }
+    },
+    "CmsoMessage" : {
+      "type" : "object",
+      "properties" : {
+        "domain" : {
+          "type" : "string",
+          "description" : "Schedule domain : ChangeManagement"
+        },
+        "scheduleId" : {
+          "type" : "string",
+          "description" : "Schedule id that must be unique within the domain. Use of UUID is highly recommended."
+        },
+        "scheduleName" : {
+          "type" : "string",
+          "description" : "User provided name of the schedule (deaults to scheduleId"
+        },
+        "userId" : {
+          "type" : "string",
+          "description" : "ATTUID of the user requesting the schedule."
+        },
+        "domainData" : {
+          "type" : "array",
+          "description" : "Domain data as name value/pairs. (i.e. CallbackUrl, CallbackData, WorkflowName)",
+          "items" : {
+            "type" : "object",
+            "additionalProperties" : {
+              "type" : "string"
+            }
+          }
+        },
+        "schedulingInfo" : {
+          "$ref" : "#/definitions/Change Management Scheduling Info"
+        }
+      }
+    },
+    "CmsoRequestError" : {
+      "type" : "object",
+      "properties" : {
+        "requestError" : {
+          "$ref" : "#/definitions/RequestError"
+        }
+      }
+    },
+    "Domain data" : {
+      "type" : "object",
+      "properties" : {
+        "name" : {
+          "type" : "string"
+        },
+        "value" : {
+          "type" : "string"
+        }
+      },
+      "description" : "Domain specific data represented as name/value pairs"
+    },
+    "HealthCheckComponent" : {
+      "type" : "object",
+      "properties" : {
+        "name" : {
+          "type" : "string"
+        },
+        "url" : {
+          "type" : "string"
+        },
+        "status" : {
+          "type" : "string"
+        },
+        "healthy" : {
+          "type" : "boolean"
+        }
+      }
+    },
+    "HealthCheckMessage" : {
+      "type" : "object",
+      "properties" : {
+        "healthy" : {
+          "type" : "boolean"
+        },
+        "buildInfo" : {
+          "type" : "string"
+        },
+        "currentTime" : {
+          "type" : "string"
+        },
+        "hostname" : {
+          "type" : "string"
+        },
+        "components" : {
+          "type" : "array",
+          "items" : {
+            "$ref" : "#/definitions/HealthCheckComponent"
+          }
+        }
+      }
+    },
+    "Name Value Data" : {
+      "type" : "object",
+      "properties" : {
+        "name" : {
+          "type" : "string",
+          "description" : "Name."
+        },
+        "value" : {
+          "type" : "object",
+          "description" : "Value."
+        }
+      },
+      "description" : "Instance of a name/value"
+    },
+    "Optimized Schedule Request" : {
+      "type" : "object",
+      "properties" : {
+        "domain" : {
+          "type" : "string",
+          "description" : "Schedule domain : ChangeManagement"
+        },
+        "scheduleId" : {
+          "type" : "string",
+          "description" : "Schedule id that must be unique within the domain. Use of UUID is highly recommended."
+        },
+        "scheduleName" : {
+          "type" : "string",
+          "description" : "User provided name of the schedule (deaults to scheduleId"
+        },
+        "userId" : {
+          "type" : "string",
+          "description" : "ATTUID of the user requesting the schedule."
+        },
+        "commonData" : {
+          "type" : "array",
+          "description" : "Implementation specific name value pairs.",
+          "items" : {
+            "$ref" : "#/definitions/Name Value Data"
+          }
+        },
+        "schedulingData" : {
+          "description" : "Scheduling data.",
+          "$ref" : "#/definitions/Change Management Scheduling Info"
+        }
+      },
+      "description" : "Request to schedule VNF change management workflow(s)."
+    },
+    "Optimizer Element" : {
+      "type" : "object",
+      "properties" : {
+        "elementId" : {
+          "type" : "string",
+          "description" : "Element identifier"
+        },
+        "elementData" : {
+          "type" : "array",
+          "description" : "Implementation specific element data.",
+          "items" : {
+            "$ref" : "#/definitions/Name Value Data"
+          }
+        },
+        "request" : {
+          "type" : "object",
+          "description" : "Request for be scheduled."
+        },
+        "groupId" : {
+          "type" : "string",
+          "description" : "VNF group identifier."
+        }
+      },
+      "description" : "Element to be scheduled."
+    },
+    "RequestError" : {
+      "type" : "object",
+      "properties" : {
+        "messageId" : {
+          "type" : "string"
+        },
+        "text" : {
+          "type" : "string"
+        },
+        "variables" : {
+          "type" : "array",
+          "items" : {
+            "type" : "string"
+          }
+        }
+      }
+    },
+    "Schedule" : {
+      "type" : "object",
+      "properties" : {
+        "createDateTime" : {
+          "type" : "string",
+          "description" : "Date/time schedule was created."
+        },
+        "optimizerDateTime" : {
+          "type" : "string"
+        },
+        "optimizerMessage" : {
+          "type" : "string"
+        },
+        "optimizerStatus" : {
+          "type" : "string"
+        },
+        "optimizerReturnDateTime" : {
+          "type" : "string"
+        },
+        "optimizerTransactionId" : {
+          "type" : "string"
+        },
+        "schedule" : {
+          "type" : "string"
+        },
+        "scheduleName" : {
+          "type" : "string"
+        },
+        "scheduleInfo" : {
+          "type" : "string"
+        },
+        "status" : {
+          "type" : "string"
+        },
+        "userId" : {
+          "type" : "string"
+        },
+        "domain" : {
+          "type" : "string"
+        },
+        "deleteDateTime" : {
+          "type" : "string"
+        },
+        "domainData" : {
+          "type" : "array",
+          "items" : {
+            "$ref" : "#/definitions/Domain data"
+          }
+        },
+        "scheduleApprovals" : {
+          "type" : "array",
+          "items" : {
+            "$ref" : "#/definitions/Schedule Approval"
+          }
+        },
+        "groups" : {
+          "type" : "array",
+          "items" : {
+            "$ref" : "#/definitions/Change Management Group"
+          }
+        }
+      }
+    },
+    "Schedule Approval" : {
+      "type" : "object",
+      "properties" : {
+        "approvalDateTime" : {
+          "type" : "string",
+          "description" : "Date/time schedule time slot was accepted/rejected."
+        },
+        "status" : {
+          "type" : "string",
+          "description" : "Approval status.",
+          "enum" : [ "Accepted", "Rejected" ]
+        },
+        "userId" : {
+          "type" : "string",
+          "description" : "ATTUID of the user accepting/rejecting the time slot."
+        }
+      },
+      "description" : "Details of a schedule approval/rejection."
+    },
+    "Schedule Approval Request" : {
+      "type" : "object",
+      "properties" : {
+        "approvalUserId" : {
+          "type" : "string",
+          "description" : "ATTUID of the user accepting/rejecting the time slot."
+        },
+        "approvalStatus" : {
+          "type" : "string",
+          "description" : "Approval status.",
+          "enum" : [ "Accepted", "Rejected" ]
+        },
+        "approvalType" : {
+          "type" : "string",
+          "description" : "Type of approval.",
+          "enum" : [ "Tier 2" ]
+        },
+        "approvalDateTime" : {
+          "type" : "string",
+          "format" : "date-time"
+        }
+      },
+      "description" : "Request to accept or reject an optimized time slot."
+    },
+    "Supported Policy Information" : {
+      "type" : "object",
+      "properties" : {
+        "policyName" : {
+          "type" : "string",
+          "description" : "Policy name"
+        },
+        "policyModifiers" : {
+          "type" : "array",
+          "description" : "Named values to modify/override policy attributes.",
+          "items" : {
+            "$ref" : "#/definitions/Name Value Data"
+          }
+        }
+      },
+      "description" : "Policy Information returned from get policies API."
+    },
+    "VNF Details" : {
+      "type" : "object",
+      "properties" : {
+        "groupId" : {
+          "type" : "string",
+          "description" : "Name of the list of VNFs to be changed as a group"
+        },
+        "node" : {
+          "type" : "array",
+          "description" : "Lists of the VNF names to be changed",
+          "items" : {
+            "type" : "string"
+          }
+        },
+        "changeWindow" : {
+          "type" : "array",
+          "description" : "Lists of desired change windows that the optimizer can select from. (Only 1 change window supported at this time)",
+          "items" : {
+            "$ref" : "#/definitions/Change Window"
+          }
+        }
+      },
+      "description" : "Details and scheduling criteria for the VNFs to be changed."
+    }
+  }
+}
\ No newline at end of file
index 0cdbf57..abc26be 100644 (file)
@@ -60,4 +60,4 @@ com.att.eelf.logging.file=logback.xml
 com.att.eelf.logging.path=\r
 \r
 logging.config=\r
-spring.profiles.active=proprietary-auth
\ No newline at end of file
+spring.profiles.active=proprietary-auth\r
index 1fb4a8f..c4f853d 100644 (file)
@@ -58,4 +58,4 @@ com.att.eelf.logging.file=logback.xml
 com.att.eelf.logging.path=
 
 logging.config=
-spring.profiles.active=aaf-auth
\ No newline at end of file
+spring.profiles.active=proprietary-auth