Improve doc for Portal API configuration 30/1030/2
authorLott, Christopher (cl778h) <cl778h@att.com>
Fri, 27 Sep 2019 14:26:24 +0000 (10:26 -0400)
committerLott, Christopher (cl778h) <cl778h@att.com>
Fri, 27 Sep 2019 15:19:52 +0000 (11:19 -0400)
Refactor some classes but no functional changes,
so did not bump the version number.

Change-Id: I42dcba55ba980f94a956c0d3990f2f6d4a9cce11
Signed-off-by: Lott, Christopher (cl778h) <cl778h@att.com>
docs/config-deploy.rst
docs/release-notes.rst
webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/PortalApiConfiguration.java [new file with mode: 0644]
webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PortalApIMockConfiguration.java [new file with mode: 0644]
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/WebSecurityMockConfiguration.java
webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/PortalRestCentralServiceTest.java

index e11c1e4..5f62be4 100644 (file)
@@ -20,32 +20,36 @@ RIC Dashboard Configuration and Deployment
 ==========================================
 
 This documents the configuration and deployment of the O-RAN SC RIC
-Dashboard web application.
+Dashboard web application, which is often deployed together with the
+ONAP Portal.
 
 Configuration
 -------------
 
-The application requires the following configuration files.  In the
-usual Kubernetes deployment, all files are provided by a configuration
-map::
+The application requires the following configuration files::
 
     application.properties
     key.properties
     portal.properties
 
+In the usual Kubernetes deployment, all file contents are provided by
+a configuration map.
 
 Application Properties
 ^^^^^^^^^^^^^^^^^^^^^^
 
-This Spring-Boot application reads key-value pairs from the file
-``application.properties`` in the current working directory when
-launched, or from the same file in a ``config`` subdirectory.  Many
-properties have default values cached within the application, in file
-``src/main/resources/application.properties``.  Properties with
+The file ``application.properties`` must be provided when the
+application is launched, either in the current working directory or in
+a ``config`` subdirectory (latter is preferred). The Helm chart that
+deploys the application should mount this file appropriately.
+
+Many properties have default values cached within the application, in
+file ``src/main/resources/application.properties``.  Properties with
 default values do NOT need to be repeated in a deployment-specific
 configuration.  Properties without default values MUST be specified in
-a deployment-specific configuration. The properties are listed below
-in alphabetical order.
+a deployment-specific configuration.
+
+The properties are listed below in alphabetical order.
 
 ``a1med.url.prefix``
 
@@ -99,7 +103,14 @@ Java class that decrypts ciphertext from Portal. Default is
 
 ``portalapi.password``
 
-Application password expected at ONAP portal. No default value.
+REST password expected at ONAP portal. No default value.
+
+``portalapi.security``
+
+Boolean flag whether the Dashboard limits access to users (browsers)
+that present security tokens set by the ONAP Portal.  If false, no
+access control is performed, which is only appropriate for isolated
+lab testing.
 
 ``portalapi.usercookie``
 
@@ -107,7 +118,7 @@ Name of request cookie with user ID. Default is ``UserId``
 
 ``portalapi.username``
 
-Application user name expected at ONAP portal. No default value.
+REST user name expected at ONAP portal. No default value.
 
 ``server.port``
 
@@ -126,9 +137,12 @@ Key Properties
 ^^^^^^^^^^^^^^
 
 The file ``key.properties`` must be provided on the Java classpath for
-the EPSDK-FW library.  A sample file is in directory
-``src/test/resources``.  The file must contain the following entries,
-listed here in alphabetical order.
+the Spring-Boot application, as required by the EPSDK-FW library. The
+Helm chart for the application should mount this file appropriately.
+A sample file is in directory ``src/test/resources``.
+
+The file must contain the following entries, listed here in
+alphabetical order.
 
 ``cipher.enc.key``
 
@@ -139,19 +153,23 @@ Portal Properties
 ^^^^^^^^^^^^^^^^^
 
 The file ``portal.properties`` must be provided on the Java classpath
-for the EPSDK-FW library.  A sample file is in directory
-``src/test/resources``.  The file must contain the following entries,
-listed here in alphabetical order.
+for the application, as required by the EPSDK-FW library.  The Helm
+chart for the application should mount this file appropriately.  A
+sample file is in directory ``src/test/resources``.
+
+The file must contain the following entries, listed here in
+alphabetical order.
 
 ``ecomp_redirect_url``
 
-URL of ONAP Portal.  No default value. Usually a value like
+Portal URL that is reachable by a user's browser.  This is a value
+like
 ``https://portal.api.simpledemo.onap.org:30225/ONAPPORTAL/login.htm``
 
 ``ecomp_rest_url``
 
-URL of ONAP Portal REST endpoint.  No default value.  Usually a value
-like ``http://portal-app.onap:8989/ONAPPORTAL/auxapi``
+Portal REST URL that is reachable by the Dashboard back-end. 
+This is a value like ``http://portal-app.onap:8989/ONAPPORTAL/auxapi``
 
 ``portal.api.impl.class``
 
@@ -172,14 +190,47 @@ Deployment
 ----------
 
 A production server requires the configuration files listed above.
-All files should be placed in a ``config`` directory.  That name is important;
-Spring automatically searches that directory for the ``application.properties``
-file. Further, that directory can easily be placed on the Java classpath so
-the additional files can be found at runtime.
-
-After creating and mounting Kubernetes config maps appropriately, launch
-the server with this command-line invocation to include the ``config`` directory
-on the Java classpath::
+All files should be placed in a ``config`` directory.  That name is
+important; Spring automatically searches that directory for the
+``application.properties`` file. Further, that directory can easily be
+placed on the Java classpath so the additional files can be found at
+runtime.
+
+
+On-Board Dashboard to ONAP Portal
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When on-boarding the Dashboard to the ONAP Portal the administrator
+must supply the following information about the deployed instance:
+
+- Dashboard URL that is reachable by a user's browser. The domain of
+  this host name must match the Portal URL that is similarly reachable
+  by a user's browser for cookie-based authentication to function as
+  expected.  This should be a value like
+  ``http://dashboard.simpledemo.onap.org:8080``
+- Dashboard REST URL that is reachable by the Portal back-end server.
+  This can be a host name or an IP address, because it does not use
+  cookie-based authentication.  This should be a value like
+  ``http://192.168.1.1:8080/auxapi/v3``
+
+The Dashboard server only listens on a single port, so the examples
+above both use the same port number.  Different port numbers might be
+required if an ingress controller or other proxy server is used.
+
+After the on-boarding process is complete, the administrator must
+enter values from the Portal for the following properties explained
+above:
+
+- ``portalapi.password``
+- ``portalapi.username``
+- ``ueb_app_key``
+
+Launch Server
+^^^^^^^^^^^^^
+
+After creating, populating and mounting Kubernetes config maps
+appropriately, launch the server with this command-line invocation to
+include the ``config`` directory on the Java classpath::
 
     java -cp config:target/ric-dash-be-1.2.0-SNAPSHOT.jar \
         -Dloader.main=org.oransc.ric.portal.dashboard.DashboardApplication \
index b574db3..2453d60 100644 (file)
@@ -19,9 +19,9 @@
 RIC Dashboard Release Notes
 ===========================
 
-Version 1.2.2, 23 Sep 2019
+Version 1.2.2, 27 Sep 2019
 --------------------------
-* Supoprt Portal security using EPSDK-FW cookie and user management
+* Support Portal security using EPSDK-FW cookie and user management
 
 Version 1.2.1, 20 Sep 2019
 --------------------------
diff --git a/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/PortalApiConfiguration.java b/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/PortalApiConfiguration.java
new file mode 100644 (file)
index 0000000..b71ed22
--- /dev/null
@@ -0,0 +1,57 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+package org.oransc.ric.portal.dashboard.config;
+
+import java.lang.invoke.MethodHandles;
+
+import org.onap.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy;
+import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+@Configuration
+@Profile("!test")
+public class PortalApiConfiguration {
+
+       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+       /**
+        * Instantiates the EPSDK-FW servlet that implements the API called by Portal.
+        * Needed because this app is not configured to scan the EPSDK-FW packages;
+        * there's also a chance that Spring-Boot does not automatically
+        * process @WebServlet annotations.
+        * 
+        * @return Servlet registration bean for the Portal Rest API proxy servlet.
+        */
+       @Bean
+       public ServletRegistrationBean<PortalRestAPIProxy> portalApiProxyServletBean() {
+               logger.debug("portalApiProxyServletBean");
+               PortalRestAPIProxy servlet = new PortalRestAPIProxy();
+               final ServletRegistrationBean<PortalRestAPIProxy> servletBean = new ServletRegistrationBean<>(servlet,
+                               PortalApiConstants.API_PREFIX + "/*");
+               servletBean.setName("PortalRestApiProxyServlet");
+               return servletBean;
+       }
+
+}
index 686b9cb..edb80c8 100644 (file)
@@ -23,7 +23,6 @@ import java.io.IOException;
 import java.lang.invoke.MethodHandles;
 import java.lang.reflect.InvocationTargetException;
 
-import org.onap.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy;
 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
 import org.oransc.ric.portal.dashboard.LoginServlet;
@@ -145,22 +144,6 @@ public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
                return portalAuthenticationFilter;
        }
 
-       /**
-        * Instantiates the EPSDK-FW servlet. Needed because this app is not configured
-        * to scan the EPSDK-FW packages; there's also a chance that Spring-Boot does
-        * not automatically process @WebServlet annotations.
-        * 
-        * @return Servlet registration bean for the Portal Rest API proxy servlet.
-        */
-       @Bean
-       public ServletRegistrationBean<PortalRestAPIProxy> portalApiProxyServletBean() {
-               PortalRestAPIProxy servlet = new PortalRestAPIProxy();
-               final ServletRegistrationBean<PortalRestAPIProxy> servletBean = new ServletRegistrationBean<>(servlet,
-                               PortalApiConstants.API_PREFIX + "/*");
-               servletBean.setName("PortalRestApiProxyServlet");
-               return servletBean;
-       }
-
        /**
         * Instantiates a trivial login servlet that serves a basic page with a link to
         * authenticate at Portal. The login filter redirects to this page instead of
diff --git a/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PortalApIMockConfiguration.java b/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PortalApIMockConfiguration.java
new file mode 100644 (file)
index 0000000..6eeae85
--- /dev/null
@@ -0,0 +1,83 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 AT&T Intellectual Property and Nokia
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================LICENSE_END===================================
+ */
+package org.oransc.ric.portal.dashboard.config;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+import java.lang.invoke.MethodHandles;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.onap.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy;
+import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
+import org.oransc.ric.portal.dashboard.portalapi.PortalAuthManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Profile;
+
+@Configuration
+@Profile("test")
+public class PortalApIMockConfiguration {
+
+       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+       // Unfortunately EPSDK-FW does not define these as constants
+       public static final String PORTAL_USERNAME_HEADER_KEY = "username";
+       public static final String PORTAL_PASSWORD_HEADER_KEY = "password";
+
+       @Bean
+       public ServletRegistrationBean<PortalRestAPIProxy> portalApiProxyServlet() {
+               PortalRestAPIProxy servlet = new PortalRestAPIProxy();
+               final ServletRegistrationBean<PortalRestAPIProxy> servletBean = new ServletRegistrationBean<>(servlet,
+                               PortalApiConstants.API_PREFIX + "/*");
+               servletBean.setName("PortalRestApiProxyServlet");
+               return servletBean;
+       }
+
+       @Bean
+       public PortalAuthManager portalAuthManager() throws Exception {
+               PortalAuthManager mockManager = mock(PortalAuthManager.class);
+               final Map<String, String> credentialsMap = new HashMap<>();
+               credentialsMap.put("appName", "appName");
+               credentialsMap.put(PORTAL_USERNAME_HEADER_KEY, PORTAL_USERNAME_HEADER_KEY);
+               credentialsMap.put(PORTAL_PASSWORD_HEADER_KEY, PORTAL_PASSWORD_HEADER_KEY);
+               doAnswer(inv -> {
+                       logger.debug("getAppCredentials");
+                       return credentialsMap;
+               }).when(mockManager).getAppCredentials();
+               doAnswer(inv -> {
+                       logger.debug("getUserId");
+                       return "userId";
+               }).when(mockManager).valdiateEcompSso(any(HttpServletRequest.class));
+               doAnswer(inv -> {
+                       logger.debug("getAppCredentials");
+                       return credentialsMap;
+               }).when(mockManager).getAppCredentials();
+               return mockManager;
+       }
+
+}
index cc9a308..8d06693 100644 (file)
  */
 package org.oransc.ric.portal.dashboard.config;
 
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-
 import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
 
-import javax.servlet.http.HttpServletRequest;
-
-import org.onap.portalsdk.core.onboarding.crossapi.PortalRestAPIProxy;
 import org.onap.portalsdk.core.onboarding.exception.PortalAPIException;
-import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
 import org.onap.portalsdk.core.restful.domain.EcompRole;
 import org.onap.portalsdk.core.restful.domain.EcompUser;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
 import org.oransc.ric.portal.dashboard.LoginServlet;
 import org.oransc.ric.portal.dashboard.portalapi.DashboardUserManager;
-import org.oransc.ric.portal.dashboard.portalapi.PortalAuthManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
@@ -67,10 +56,6 @@ public class WebSecurityMockConfiguration extends WebSecurityConfigurerAdapter {
        public static final String TEST_CRED_ADMIN = "admin";
        public static final String TEST_CRED_STANDARD = "standard";
 
-       // Unfortunately EPSDK-FW does not define these as constants
-       public static final String PORTAL_USERNAME_HEADER_KEY = "username";
-       public static final String PORTAL_PASSWORD_HEADER_KEY = "password";
-
        private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
        public WebSecurityMockConfiguration(@Value("${userfile}") final String userFilePath) {
@@ -116,37 +101,6 @@ public class WebSecurityMockConfiguration extends WebSecurityConfigurerAdapter {
                return servletBean;
        }
 
-       @Bean
-       public ServletRegistrationBean<PortalRestAPIProxy> portalApiProxyServlet() {
-               PortalRestAPIProxy servlet = new PortalRestAPIProxy();
-               final ServletRegistrationBean<PortalRestAPIProxy> servletBean = new ServletRegistrationBean<>(servlet,
-                               PortalApiConstants.API_PREFIX + "/*");
-               servletBean.setName("PortalRestApiProxyServlet");
-               return servletBean;
-       }
-
-       @Bean
-       public PortalAuthManager portalAuthManager() throws Exception {
-               PortalAuthManager mockManager = mock(PortalAuthManager.class);
-               final Map<String, String> credentialsMap = new HashMap<>();
-               credentialsMap.put("appName", "appName");
-               credentialsMap.put(PORTAL_USERNAME_HEADER_KEY, PORTAL_USERNAME_HEADER_KEY);
-               credentialsMap.put(PORTAL_PASSWORD_HEADER_KEY, PORTAL_PASSWORD_HEADER_KEY);
-               doAnswer(inv -> {
-                       logger.debug("getAppCredentials");
-                       return credentialsMap;
-               }).when(mockManager).getAppCredentials();
-               doAnswer(inv -> {
-                       logger.debug("getUserId");
-                       return "userId";
-               }).when(mockManager).valdiateEcompSso(any(HttpServletRequest.class));
-               doAnswer(inv -> {
-                       logger.debug("getAppCredentials");
-                       return credentialsMap;
-               }).when(mockManager).getAppCredentials();
-               return mockManager;
-       }
-
        // This implementation is so light it can be used during tests.
        @Bean
        public DashboardUserManager dashboardUserManager() throws IOException, PortalAPIException {
index 509dda7..bb31028 100644 (file)
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
 import org.onap.portalsdk.core.restful.domain.EcompUser;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
-import org.oransc.ric.portal.dashboard.config.WebSecurityMockConfiguration;
+import org.oransc.ric.portal.dashboard.config.PortalApIMockConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpEntity;
@@ -62,10 +62,10 @@ public class PortalRestCentralServiceTest extends AbstractControllerTest {
 
        private HttpEntity<Object> getEntityWithHeaders(Object body) {
                HttpHeaders headers = new HttpHeaders();
-               headers.set(WebSecurityMockConfiguration.PORTAL_USERNAME_HEADER_KEY,
-                               WebSecurityMockConfiguration.PORTAL_USERNAME_HEADER_KEY);
-               headers.set(WebSecurityMockConfiguration.PORTAL_PASSWORD_HEADER_KEY,
-                               WebSecurityMockConfiguration.PORTAL_PASSWORD_HEADER_KEY);
+               headers.set(PortalApIMockConfiguration.PORTAL_USERNAME_HEADER_KEY,
+                               PortalApIMockConfiguration.PORTAL_USERNAME_HEADER_KEY);
+               headers.set(PortalApIMockConfiguration.PORTAL_PASSWORD_HEADER_KEY,
+                               PortalApIMockConfiguration.PORTAL_PASSWORD_HEADER_KEY);
                HttpEntity<Object> entity = new HttpEntity<>(body, headers);
                return entity;
        }