Merge "New version of NearRT-RIC simulator"
authorHenrik Andersson <henrik.b.andersson@est.tech>
Fri, 17 Jan 2020 13:20:05 +0000 (13:20 +0000)
committerGerrit Code Review <gerrit@o-ran-sc.org>
Fri, 17 Jan 2020 13:20:05 +0000 (13:20 +0000)
67 files changed:
.gitignore
dashboard/webapp-backend/eclipse-formatter.xml [moved from policy-agent/java-formatter.xml with 100% similarity]
dashboard/webapp-backend/pom.xml
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardApplication.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardConstants.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/DashboardUserManager.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/AdminConfiguration.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/PortalApiConfiguration.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/SpringContextCache.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/SwaggerConfiguration.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/config/WebSecurityConfiguration.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/CustomResponseEntityExceptionHandler.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/Html5PathsController.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/PolicyController.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/controller/SimpleErrorController.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/k8sapi/SimpleKubernetesClient.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/EcompUserDetails.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/ErrorTransport.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInfo.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyInstances.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyType.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/PolicyTypes.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/model/SuccessTransport.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApi.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/IPortalSdkDecryptor.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthManager.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalAuthenticationFilter.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalRestCentralServiceImpl.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalSdkDecryptorAes.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/portalapi/PortalSdkDecryptorPkc.java
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/util/HttpsURLConnectionUtils.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/DashboardTestServer.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PolicyControllerMockConfiguration.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/PortalApIMockConfiguration.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/config/WebSecurityMockConfiguration.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/AbstractControllerTest.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/DefaultContextTest.java
dashboard/webapp-backend/src/test/java/org/oransc/ric/portal/dashboard/controller/PortalRestCentralServiceTest.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1Client.java
policy-agent/src/main/java/org/oransc/policyagent/clients/A1ClientImpl.java
policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfig.java
policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java [deleted file]
policy-agent/src/main/java/org/oransc/policyagent/controllers/PolicyController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/RicRepositoryController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceRegistrationInfo.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Policies.java
policy-agent/src/main/java/org/oransc/policyagent/repository/PolicyTypes.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Ric.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Rics.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/RepositorySupervision.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/RicRecoveryTask.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/StartupService.java
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java
policy-agent/src/test/java/org/oransc/policyagent/clients/A1ClientImplTest.java
policy-agent/src/test/java/org/oransc/policyagent/configuration/ApplicationConfigTest.java
policy-agent/src/test/java/org/oransc/policyagent/tasks/RepositorySupervisionTest.java
policy-agent/src/test/java/org/oransc/policyagent/tasks/StartupServiceTest.java
policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java [new file with mode: 0644]
policy-agent/src/test/resources/policy_types/demo-policy-schema-1.json
policy-agent/src/test/resources/policy_types/demo-policy-schema-3.json
policy-agent/src/test/resources/test_application_configuration.json

index 67d6d0f..90c40a4 100644 (file)
@@ -3,3 +3,7 @@
 .tox
 docs/_build/
 .DS_STORE
+
+# Eclipse
+.checkstyle
+.sts4-cache
\ No newline at end of file
index 80bb585..095abef 100644 (file)
@@ -36,6 +36,8 @@ limitations under the License.
     <properties>
         <springfox.version>2.9.2</springfox.version>
         <immutable.version>2.7.1</immutable.version>
+        <formatter-maven-plugin.version>2.8.1</formatter-maven-plugin.version>
+        <spotless-maven-plugin.version>1.18.0</spotless-maven-plugin.version>
         <!-- Set by Jenkins -->
         <build.number>0</build.number>
     </properties>
@@ -164,8 +166,6 @@ limitations under the License.
         <dependency>
             <groupId>org.junit.platform</groupId>
             <artifactId>junit-platform-launcher</artifactId>
-            <!-- Override Spring-Boot choice for Eclipse -->
-            <version>1.4.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
@@ -175,6 +175,32 @@ limitations under the License.
                 <groupId>org.springframework.boot</groupId>
                 <artifactId>spring-boot-maven-plugin</artifactId>
             </plugin>
+            <plugin>
+                <groupId>net.revelc.code.formatter</groupId>
+                <artifactId>formatter-maven-plugin</artifactId>
+                <version>${formatter-maven-plugin.version}</version>
+                <configuration>
+                    <configFile>${project.basedir}/eclipse-formatter.xml</configFile>
+                </configuration>
+                <!-- https://code.revelc.net/formatter-maven-plugin/ use
+                    mvn formatter:format spotless:apply process-sources -->
+            </plugin>
+            <plugin>
+                <groupId>com.diffplug.spotless</groupId>
+                <artifactId>spotless-maven-plugin</artifactId>
+                <version>${spotless-maven-plugin.version}</version>
+                <configuration>
+                    <java>
+                        <removeUnusedImports />
+                        <importOrder>
+                            <order>com,java,javax,org</order>
+                        </importOrder>
+                    </java>
+                </configuration>
+                <!-- https://github.com/diffplug/spotless/tree/master/plugin-maven
+                    use mvn spotless:apply to rewrite source files use mvn spotless:check to
+                    validate source files -->
+            </plugin>
             <plugin>
                 <!-- Most configuration and all execution is inherited -->
                 <groupId>org.codehaus.mojo</groupId>
index 333c532..2550b8e 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,27 +34,27 @@ import org.springframework.context.annotation.ComponentScan;
 @ComponentScan("org.oransc.ric.portal.dashboard")
 public class DashboardApplication {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       public static void main(String[] args) throws IOException {
-               SpringApplication.run(DashboardApplication.class, args);
-               // Ensure this appears on the console by using level WARN
-               logger.warn("main: version '{}' successful start",
-                               getImplementationVersion(MethodHandles.lookup().lookupClass()));
-       }
-
-       /**
-        * Gets version details for the specified class.
-        * 
-        * @param clazz
-        *                  Class to get the version
-        * 
-        * @return the value of the MANIFEST.MF property Implementation-Version as
-        *         written by maven when packaged in a jar; 'unknown' otherwise.
-        */
-       public static String getImplementationVersion(Class<?> clazz) {
-               String classPath = clazz.getResource(clazz.getSimpleName() + ".class").toString();
-               return classPath.startsWith("jar") ? clazz.getPackage().getImplementationVersion() : "unknown-not-jar";
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    public static void main(String[] args) throws IOException {
+        SpringApplication.run(DashboardApplication.class, args);
+        // Ensure this appears on the console by using level WARN
+        logger.warn("main: version '{}' successful start",
+            getImplementationVersion(MethodHandles.lookup().lookupClass()));
+    }
+
+    /**
+     * Gets version details for the specified class.
+     *
+     * @param clazz
+     *        Class to get the version
+     *
+     * @return the value of the MANIFEST.MF property Implementation-Version as
+     *         written by maven when packaged in a jar; 'unknown' otherwise.
+     */
+    public static String getImplementationVersion(Class<?> clazz) {
+        String classPath = clazz.getResource(clazz.getSimpleName() + ".class").toString();
+        return classPath.startsWith("jar") ? clazz.getPackage().getImplementationVersion() : "unknown-not-jar";
+    }
 
 }
index b82aa64..4b5d9a4 100644 (file)
@@ -21,24 +21,24 @@ package org.oransc.ric.portal.dashboard;
 
 public abstract class DashboardConstants {
 
-       private DashboardConstants() {
-               // Sonar insists on hiding the constructor
-       }
+    private DashboardConstants() {
+        // Sonar insists on hiding the constructor
+    }
 
-       public static final String ENDPOINT_PREFIX = "/api";
-       // Factor out method names used in multiple controllers
-       public static final String VERSION_METHOD = "version";
-       public static final String APP_NAME_AC = "AC";
-       public static final String APP_NAME_MC = "MC";
-       // The role names are defined by ONAP Portal.
-       // The prefix "ROLE_" is required by Spring.
-       // These are used in Java code annotations that require constants.
-       public static final String ROLE_NAME_STANDARD = "Standard_User";
-       public static final String ROLE_NAME_ADMIN = "System_Administrator";
-       private static final String ROLE_PREFIX = "ROLE_";
-       public static final String ROLE_ADMIN = ROLE_PREFIX + ROLE_NAME_ADMIN;
-       public static final String ROLE_STANDARD = ROLE_PREFIX + ROLE_NAME_STANDARD;
-       public static final String POLICY_CONTROLLER_USERNAME = "admin";
-       public static final String POLICY_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U";
+    public static final String ENDPOINT_PREFIX = "/api";
+    // Factor out method names used in multiple controllers
+    public static final String VERSION_METHOD = "version";
+    public static final String APP_NAME_AC = "AC";
+    public static final String APP_NAME_MC = "MC";
+    // The role names are defined by ONAP Portal.
+    // The prefix "ROLE_" is required by Spring.
+    // These are used in Java code annotations that require constants.
+    public static final String ROLE_NAME_STANDARD = "Standard_User";
+    public static final String ROLE_NAME_ADMIN = "System_Administrator";
+    private static final String ROLE_PREFIX = "ROLE_";
+    public static final String ROLE_ADMIN = ROLE_PREFIX + ROLE_NAME_ADMIN;
+    public static final String ROLE_STANDARD = ROLE_PREFIX + ROLE_NAME_STANDARD;
+    public static final String POLICY_CONTROLLER_USERNAME = "admin";
+    public static final String POLICY_CONTROLLER_PASSWORD = "Kp8bJ4SXszM0WXlhak3eHlcse2gAw84vaoGGmJvUy2U";
 
 }
index c5fd101..ffb7396 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  */
 package org.oransc.ric.portal.dashboard;
 
+import com.fasterxml.jackson.core.JsonGenerationException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
 import java.io.File;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
@@ -33,152 +38,146 @@ import org.onap.portalsdk.core.restful.domain.EcompUser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.type.TypeReference;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
 /**
  * Provides simple user-management services.
- * 
+ *
  * This first implementation serializes user details to a file.
- * 
+ *
  * TODO: migrate to a database.
  */
 public class DashboardUserManager {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       // This default value is only useful for development and testing.
-       public static final String USER_FILE_PATH = "dashboard-users.json";
-
-       private final File userFile;
-       private final List<EcompUser> users;
-
-       /**
-        * Development/test-only constructor that uses default file path.
-        * 
-        * @param clear
-        *                  If true, start empty and remove any existing file.
-        * 
-        * @throws IOException
-        *                         On file error
-        */
-       public DashboardUserManager(boolean clear) throws IOException {
-               this(USER_FILE_PATH);
-               if (clear) {
-                       logger.debug("ctor: removing file {}", userFile.getAbsolutePath());
-                       File f = new File(DashboardUserManager.USER_FILE_PATH);
-                       if (f.exists())
-                               f.delete();
-                       users.clear();
-               }
-       }
-
-       /**
-        * Constructur that accepts a file path
-        * 
-        * @param userFilePath
-        *                         File path
-        * @throws IOException
-        *                         If file cannot be read
-        */
-       public DashboardUserManager(final String userFilePath) throws IOException {
-               logger.debug("ctor: userfile {}", userFilePath);
-               if (userFilePath == null)
-                       throw new IllegalArgumentException("Missing or empty user file property");
-               userFile = new File(userFilePath);
-               logger.debug("ctor: managing users in file {}", userFile.getAbsolutePath());
-               if (userFile.exists()) {
-                       final ObjectMapper mapper = new ObjectMapper();
-                       users = mapper.readValue(userFile, new TypeReference<List<EcompUser>>() {
-                       });
-               } else {
-                       users = new ArrayList<>();
-               }
-       }
-
-       /**
-        * Gets the current users.
-        * 
-        * @return List of EcompUser objects, possibly empty
-        */
-       public List<EcompUser> getUsers() {
-               return this.users;
-       }
-
-       /**
-        * Gets the user with the specified login Id
-        * 
-        * @param loginId
-        *                    Desired login Id
-        * @return User object; null if Id is not known
-        */
-       public EcompUser getUser(String loginId) {
-               for (EcompUser u : this.users) {
-                       if (u.getLoginId().equals(loginId)) {
-                               logger.debug("getUser: match on {}", loginId);
-                               return u;
-                       }
-               }
-               logger.debug("getUser: no match on {}", loginId);
-               return null;
-       }
-
-       private void saveUsers() throws JsonGenerationException, JsonMappingException, IOException {
-               final ObjectMapper mapper = new ObjectMapper();
-               mapper.writeValue(userFile, users);
-       }
-
-       /*
-        * Allow at most one thread to create a user at one time.
-        */
-       public synchronized void createUser(EcompUser user) throws PortalAPIException {
-               logger.debug("createUser: loginId is " + user.getLoginId());
-               if (users.contains(user))
-                       throw new PortalAPIException("User exists: " + user.getLoginId());
-               users.add(user);
-               try {
-                       saveUsers();
-               } catch (Exception ex) {
-                       throw new PortalAPIException("Save failed", ex);
-               }
-       }
-
-       /*
-        * Allow at most one thread to modify a user at one time. We still have
-        * last-edit-wins of course.
-        */
-       public synchronized void updateUser(String loginId, EcompUser user) throws PortalAPIException {
-               logger.debug("editUser: loginId is " + loginId);
-               int index = users.indexOf(user);
-               if (index < 0)
-                       throw new PortalAPIException("User does not exist: " + user.getLoginId());
-               users.remove(index);
-               users.add(user);
-               try {
-                       saveUsers();
-               } catch (Exception ex) {
-                       throw new PortalAPIException("Save failed", ex);
-               }
-       }
-
-       // Test infrastructure
-       public static void main(String[] args) throws Exception {
-               DashboardUserManager dum = new DashboardUserManager(false);
-               EcompUser user = new EcompUser();
-               user.setActive(true);
-               user.setLoginId("demo");
-               user.setFirstName("First");
-               user.setLastName("Last");
-               EcompRole role = new EcompRole();
-               role.setId(1L);
-               role.setName(DashboardConstants.ROLE_NAME_ADMIN);
-               Set<EcompRole> roles = new HashSet<>();
-               roles.add(role);
-               user.setRoles(roles);
-               dum.createUser(user);
-               logger.debug("Created user {}", user);
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    // This default value is only useful for development and testing.
+    public static final String USER_FILE_PATH = "dashboard-users.json";
+
+    private final File userFile;
+    private final List<EcompUser> users;
+
+    /**
+     * Development/test-only constructor that uses default file path.
+     *
+     * @param clear
+     *        If true, start empty and remove any existing file.
+     *
+     * @throws IOException
+     *         On file error
+     */
+    public DashboardUserManager(boolean clear) throws IOException {
+        this(USER_FILE_PATH);
+        if (clear) {
+            logger.debug("ctor: removing file {}", userFile.getAbsolutePath());
+            File f = new File(DashboardUserManager.USER_FILE_PATH);
+            if (f.exists())
+                f.delete();
+            users.clear();
+        }
+    }
+
+    /**
+     * Constructur that accepts a file path
+     *
+     * @param userFilePath
+     *        File path
+     * @throws IOException
+     *         If file cannot be read
+     */
+    public DashboardUserManager(final String userFilePath) throws IOException {
+        logger.debug("ctor: userfile {}", userFilePath);
+        if (userFilePath == null)
+            throw new IllegalArgumentException("Missing or empty user file property");
+        userFile = new File(userFilePath);
+        logger.debug("ctor: managing users in file {}", userFile.getAbsolutePath());
+        if (userFile.exists()) {
+            final ObjectMapper mapper = new ObjectMapper();
+            users = mapper.readValue(userFile, new TypeReference<List<EcompUser>>() {});
+        } else {
+            users = new ArrayList<>();
+        }
+    }
+
+    /**
+     * Gets the current users.
+     *
+     * @return List of EcompUser objects, possibly empty
+     */
+    public List<EcompUser> getUsers() {
+        return this.users;
+    }
+
+    /**
+     * Gets the user with the specified login Id
+     *
+     * @param loginId
+     *        Desired login Id
+     * @return User object; null if Id is not known
+     */
+    public EcompUser getUser(String loginId) {
+        for (EcompUser u : this.users) {
+            if (u.getLoginId().equals(loginId)) {
+                logger.debug("getUser: match on {}", loginId);
+                return u;
+            }
+        }
+        logger.debug("getUser: no match on {}", loginId);
+        return null;
+    }
+
+    private void saveUsers() throws JsonGenerationException, JsonMappingException, IOException {
+        final ObjectMapper mapper = new ObjectMapper();
+        mapper.writeValue(userFile, users);
+    }
+
+    /*
+     * Allow at most one thread to create a user at one time.
+     */
+    public synchronized void createUser(EcompUser user) throws PortalAPIException {
+        logger.debug("createUser: loginId is " + user.getLoginId());
+        if (users.contains(user))
+            throw new PortalAPIException("User exists: " + user.getLoginId());
+        users.add(user);
+        try {
+            saveUsers();
+        } catch (Exception ex) {
+            throw new PortalAPIException("Save failed", ex);
+        }
+    }
+
+    /*
+     * Allow at most one thread to modify a user at one time. We still have
+     * last-edit-wins of course.
+     */
+    public synchronized void updateUser(String loginId, EcompUser user) throws PortalAPIException {
+        logger.debug("editUser: loginId is " + loginId);
+        int index = users.indexOf(user);
+        if (index < 0)
+            throw new PortalAPIException("User does not exist: " + user.getLoginId());
+        users.remove(index);
+        users.add(user);
+        try {
+            saveUsers();
+        } catch (Exception ex) {
+            throw new PortalAPIException("Save failed", ex);
+        }
+    }
+
+    // Test infrastructure
+    public static void main(String[] args) throws Exception {
+        DashboardUserManager dum = new DashboardUserManager(false);
+        EcompUser user = new EcompUser();
+        user.setActive(true);
+        user.setLoginId("demo");
+        user.setFirstName("First");
+        user.setLastName("Last");
+        EcompRole role = new EcompRole();
+        role.setId(1L);
+        role.setName(DashboardConstants.ROLE_NAME_ADMIN);
+        Set<EcompRole> roles = new HashSet<>();
+        roles.add(role);
+        user.setRoles(roles);
+        dum.createUser(user);
+        logger.debug("Created user {}", user);
+    }
 
 }
index 696d74f..8c646fe 100644 (file)
@@ -38,21 +38,21 @@ import org.springframework.context.annotation.Profile;
 @Profile("!test")
 public class AdminConfiguration {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       // Populated by the autowired constructor
-       private final String userfile;
-
-       @Autowired
-       public AdminConfiguration(@Value("${userfile}") final String userfile) {
-               logger.debug("ctor userfile '{}'", userfile);
-               this.userfile = userfile;
-       }
-
-       @Bean
-       // The bean (method) name must be globally unique
-       public DashboardUserManager userManager() throws IOException {
-               return new DashboardUserManager(userfile);
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    // Populated by the autowired constructor
+    private final String userfile;
+
+    @Autowired
+    public AdminConfiguration(@Value("${userfile}") final String userfile) {
+        logger.debug("ctor userfile '{}'", userfile);
+        this.userfile = userfile;
+    }
+
+    @Bean
+    // The bean (method) name must be globally unique
+    public DashboardUserManager userManager() throws IOException {
+        return new DashboardUserManager(userfile);
+    }
 
 }
index f318cad..520f27f 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -34,24 +34,24 @@ import org.springframework.context.annotation.Profile;
 @Profile("!test")
 public class PortalApiConfiguration {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    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;
-       }
+    /**
+     * 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 3a87782..a2f3d8f 100644 (file)
@@ -30,15 +30,15 @@ import org.springframework.stereotype.Component;
 @Component
 public class SpringContextCache implements ApplicationContextAware {
 
-       private static ApplicationContext applicationContext = null;
+    private static ApplicationContext applicationContext = null;
 
-       @Override
-       public void setApplicationContext(final ApplicationContext appContext) throws BeansException {
-               applicationContext = appContext;
-       }
+    @Override
+    public void setApplicationContext(final ApplicationContext appContext) throws BeansException {
+        applicationContext = appContext;
+    }
 
-       public static ApplicationContext getApplicationContext() {
-               return applicationContext;
-       }
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
 
 }
index b4bb0a3..435414a 100644 (file)
@@ -40,29 +40,29 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
 @EnableSwagger2
 public class SwaggerConfiguration {
 
-       /**
-        * @return new Docket
-        */
-       @Bean
-       public Docket api() {
-               return new Docket(DocumentationType.SWAGGER_2).select() //
-                               .apis(RequestHandlerSelectors.basePackage(DashboardApplication.class.getPackage().getName())) //
-                               .paths(PathSelectors.any()) //
-                               .build() //
-                               .apiInfo(apiInfo());
-       }
+    /**
+     * @return new Docket
+     */
+    @Bean
+    public Docket api() {
+        return new Docket(DocumentationType.SWAGGER_2).select() //
+            .apis(RequestHandlerSelectors.basePackage(DashboardApplication.class.getPackage().getName())) //
+            .paths(PathSelectors.any()) //
+            .build() //
+            .apiInfo(apiInfo());
+    }
 
-       private ApiInfo apiInfo() {
-               final String version = DashboardApplication.class.getPackage().getImplementationVersion();
-               return new ApiInfoBuilder() //
-                               .title("RIC Dashboard backend") //
-                               .description("Proxies access to RIC services.")//
-                               .termsOfServiceUrl("Terms of service") //
-                               .contact(new Contact("RIC Dashboard Dev Team", //
-                                               "http://no-docs-yet.org/", //
-                                               "noreply@O-RAN-SC.org")) //
-                               .license("Apache 2.0 License").licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") //
-                               .version(version == null ? "version not available" : version) //
-                               .build();
-       }
+    private ApiInfo apiInfo() {
+        final String version = DashboardApplication.class.getPackage().getImplementationVersion();
+        return new ApiInfoBuilder() //
+            .title("RIC Dashboard backend") //
+            .description("Proxies access to RIC services.")//
+            .termsOfServiceUrl("Terms of service") //
+            .contact(new Contact("RIC Dashboard Dev Team", //
+                "http://no-docs-yet.org/", //
+                "noreply@O-RAN-SC.org")) //
+            .license("Apache 2.0 License").licenseUrl("http://www.apache.org/licenses/LICENSE-2.0") //
+            .version(version == null ? "version not available" : version) //
+            .build();
+    }
 }
index 85a96d0..b43f8a9 100644 (file)
@@ -26,6 +26,7 @@ import java.lang.reflect.InvocationTargetException;
 
 import org.onap.portalsdk.core.onboarding.util.PortalApiConstants;
 import org.oransc.ric.portal.dashboard.DashboardUserManager;
+import org.oransc.ric.portal.dashboard.controller.PolicyController;
 import org.oransc.ric.portal.dashboard.controller.SimpleErrorController;
 import org.oransc.ric.portal.dashboard.portalapi.PortalAuthManager;
 import org.oransc.ric.portal.dashboard.portalapi.PortalAuthenticationFilter;
@@ -43,7 +44,6 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
 import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
-import org.oransc.ric.portal.dashboard.controller.PolicyController;
 
 @Configuration
 @EnableWebSecurity
@@ -51,77 +51,77 @@ import org.oransc.ric.portal.dashboard.controller.PolicyController;
 @Profile("!test")
 public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       // Although constructor arguments are recommended over field injection,
-       // this results in fewer lines of code.
-       @Value("${portalapi.security}")
-       private Boolean portalapiSecurity;
-       @Value("${portalapi.appname}")
-       private String appName;
-       @Value("${portalapi.username}")
-       private String userName;
-       @Value("${portalapi.password}")
-       private String password;
-       @Value("${portalapi.decryptor}")
-       private String decryptor;
-       @Value("${portalapi.usercookie}")
-       private String userCookie;
+    // Although constructor arguments are recommended over field injection,
+    // this results in fewer lines of code.
+    @Value("${portalapi.security}")
+    private Boolean portalapiSecurity;
+    @Value("${portalapi.appname}")
+    private String appName;
+    @Value("${portalapi.username}")
+    private String userName;
+    @Value("${portalapi.password}")
+    private String password;
+    @Value("${portalapi.decryptor}")
+    private String decryptor;
+    @Value("${portalapi.usercookie}")
+    private String userCookie;
 
-       @Autowired
-       DashboardUserManager userManager;
+    @Autowired
+    DashboardUserManager userManager;
 
-       @Override
-       protected void configure(HttpSecurity http) throws Exception {
-               logger.debug("configure: portalapi.username {}", userName);
-               // A chain of ".and()" always baffles me
-               http.authorizeRequests().anyRequest().authenticated();
-               http.headers().frameOptions().disable();
-               http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
-               http.addFilterBefore(portalAuthenticationFilterBean(), BasicAuthenticationFilter.class);
-       }
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        logger.debug("configure: portalapi.username {}", userName);
+        // A chain of ".and()" always baffles me
+        http.authorizeRequests().anyRequest().authenticated();
+        http.headers().frameOptions().disable();
+        http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
+        http.addFilterBefore(portalAuthenticationFilterBean(), BasicAuthenticationFilter.class);
+    }
 
-       /**
-        * Resource paths that do not require authentication, especially including
-        * Swagger-generated documentation.
-        */
-       public static final String[] OPEN_PATHS = { //
-                       "/v2/api-docs", //
-                       "/swagger-resources/**", //
-                       "/swagger-ui.html", //
-                       "/webjars/**", //
-                       PortalApiConstants.API_PREFIX + "/**", //
-                       PolicyController.CONTROLLER_PATH + "/" + PolicyController.VERSION_METHOD, //
-                       SimpleErrorController.ERROR_PATH };
+    /**
+     * Resource paths that do not require authentication, especially including
+     * Swagger-generated documentation.
+     */
+    public static final String[] OPEN_PATHS = { //
+        "/v2/api-docs", //
+        "/swagger-resources/**", //
+        "/swagger-ui.html", //
+        "/webjars/**", //
+        PortalApiConstants.API_PREFIX + "/**", //
+        PolicyController.CONTROLLER_PATH + "/" + PolicyController.VERSION_METHOD, //
+        SimpleErrorController.ERROR_PATH};
 
-       @Override
-       public void configure(WebSecurity web) throws Exception {
-               // This disables Spring security, but not the app's filter.
-               web.ignoring().antMatchers(OPEN_PATHS);
-       }
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        // This disables Spring security, but not the app's filter.
+        web.ignoring().antMatchers(OPEN_PATHS);
+    }
 
-       @Bean
-       public PortalAuthManager portalAuthManagerBean()
-                       throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException,
-                       IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
-               return new PortalAuthManager(appName, userName, password, decryptor, userCookie);
-       }
+    @Bean
+    public PortalAuthManager portalAuthManagerBean()
+        throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException,
+        IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+        return new PortalAuthManager(appName, userName, password, decryptor, userCookie);
+    }
 
-       /*
-        * If this is annotated with @Bean, it is created automatically AND REGISTERED,
-        * and Spring processes annotations in the source of the class. However, the
-        * filter is added in the chain apparently in the wrong order. Alternately, with
-        * no @Bean and added to the chain up in the configure() method in the desired
-        * order, the ignoring() matcher pattern configured above causes Spring to
-        * bypass this filter, which seems to me means the filter participates
-        * correctly.
-        */
-       public PortalAuthenticationFilter portalAuthenticationFilterBean()
-                       throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException,
-                       IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
-               PortalAuthenticationFilter portalAuthenticationFilter = new PortalAuthenticationFilter(portalapiSecurity,
-                               portalAuthManagerBean(), this.userManager);
-               return portalAuthenticationFilter;
-       }
+    /*
+     * If this is annotated with @Bean, it is created automatically AND REGISTERED,
+     * and Spring processes annotations in the source of the class. However, the
+     * filter is added in the chain apparently in the wrong order. Alternately, with
+     * no @Bean and added to the chain up in the configure() method in the desired
+     * order, the ignoring() matcher pattern configured above causes Spring to
+     * bypass this filter, which seems to me means the filter participates
+     * correctly.
+     */
+    public PortalAuthenticationFilter portalAuthenticationFilterBean()
+        throws ClassNotFoundException, InstantiationException, IllegalAccessException, IOException,
+        IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+        PortalAuthenticationFilter portalAuthenticationFilter =
+            new PortalAuthenticationFilter(portalapiSecurity, portalAuthManagerBean(), this.userManager);
+        return portalAuthenticationFilter;
+    }
 
 }
index f5ecd10..52a51fb 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,7 +36,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
 /**
  * Catches certain exceptions. This controller advice factors out try-catch
  * blocks in many controller methods.
- * 
+ *
  * Also see:<br>
  * https://www.baeldung.com/exception-handling-for-rest-with-spring
  * https://www.springboottutorial.com/spring-boot-exception-handling-for-rest-services
@@ -44,39 +44,39 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
 @ControllerAdvice
 public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {
 
-       // Superclass has "logger" that is exposed here, so use a different name
-       private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    // Superclass has "logger" that is exposed here, so use a different name
+    private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       /**
-        * Logs the error and generates a JSON response when a REST controller method
-        * takes a RestClientResponseException. This is thrown by the Http client when a
-        * remote method returns a non-2xx code. All the controller methods are proxies
-        * in that they just forward the request along to a remote system, so if that
-        * remote system fails, return 502 plus some details about the failure, rather
-        * than the generic 500 that Spring-Boot will return on an uncaught exception.
-        * 
-        * Why 502? I quote: <blockquote>HTTP server received an invalid response from a
-        * server it consulted when acting as a proxy or gateway.</blockquote>
-        * 
-        * @param ex
-        *                    The exception
-        * 
-        * @param request
-        *                    The original request
-        * 
-        * @return A response entity with status code 502 plus some details in the body.
-        */
-       @ExceptionHandler({ RestClientResponseException.class })
-       public final ResponseEntity<ErrorTransport> handleProxyMethodException(Exception ex, WebRequest request) {
-               // Capture the full stack trace in the log.
-               log.error("handleProxyMethodException: request {}, exception {}", request.getDescription(false), ex);
-               if (ex instanceof HttpStatusCodeException) {
-                       HttpStatusCodeException hsce = (HttpStatusCodeException) ex;
-                       return new ResponseEntity<>(new ErrorTransport(hsce.getRawStatusCode(), hsce.getResponseBodyAsString(),
-                                       ex.toString(), request.getDescription(false)), HttpStatus.BAD_GATEWAY);
-               } else {
-                       return new ResponseEntity<>(new ErrorTransport(500, ex), HttpStatus.BAD_GATEWAY);
-               }
-       }
+    /**
+     * Logs the error and generates a JSON response when a REST controller method
+     * takes a RestClientResponseException. This is thrown by the Http client when a
+     * remote method returns a non-2xx code. All the controller methods are proxies
+     * in that they just forward the request along to a remote system, so if that
+     * remote system fails, return 502 plus some details about the failure, rather
+     * than the generic 500 that Spring-Boot will return on an uncaught exception.
+     *
+     * Why 502? I quote: <blockquote>HTTP server received an invalid response from a
+     * server it consulted when acting as a proxy or gateway.</blockquote>
+     *
+     * @param ex
+     *        The exception
+     *
+     * @param request
+     *        The original request
+     *
+     * @return A response entity with status code 502 plus some details in the body.
+     */
+    @ExceptionHandler({RestClientResponseException.class})
+    public final ResponseEntity<ErrorTransport> handleProxyMethodException(Exception ex, WebRequest request) {
+        // Capture the full stack trace in the log.
+        log.error("handleProxyMethodException: request {}, exception {}", request.getDescription(false), ex);
+        if (ex instanceof HttpStatusCodeException) {
+            HttpStatusCodeException hsce = (HttpStatusCodeException) ex;
+            return new ResponseEntity<>(new ErrorTransport(hsce.getRawStatusCode(), hsce.getResponseBodyAsString(),
+                ex.toString(), request.getDescription(false)), HttpStatus.BAD_GATEWAY);
+        } else {
+            return new ResponseEntity<>(new ErrorTransport(500, ex), HttpStatus.BAD_GATEWAY);
+        }
+    }
 
 }
index 7fb6e67..5d80538 100644 (file)
@@ -8,9 +8,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -39,30 +39,31 @@ import org.springframework.web.bind.annotation.RequestMethod;
 @Controller
 public class Html5PathsController {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       /**
-        * Forwards the browser to the index (main) page upon request of a known route.
-        * This unfortunately requires duplication of the Angular route strings in the
-        * path mappings on this method. Could switch to a regex pattern instead someday
-        * if the routes change too often.
-        * 
-        * https://stackoverflow.com/questions/44692781/configure-spring-boot-to-redirect-404-to-a-single-page-app
-        * 
-        * @param request
-        *                     HttpServletRequest
-        * @param response
-        *                     HttpServletResponse
-        * @throws IOException
-        *                         On error
-        */
-       @RequestMapping(method = { RequestMethod.OPTIONS, RequestMethod.GET }, //
-                       path = { "/policy", "/user" })
-       public void forwardAngularRoutes(HttpServletRequest request, HttpServletResponse response) throws IOException {
-               URL url = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), "/index.html");
-               if (logger.isDebugEnabled())
-                       logger.debug("forwardAngularRoutes: {} redirected to {}", request.getRequestURI(), url);
-               response.sendRedirect(url.toString());
-       }
+    /**
+     * Forwards the browser to the index (main) page upon request of a known route.
+     * This unfortunately requires duplication of the Angular route strings in the
+     * path mappings on this method. Could switch to a regex pattern instead someday
+     * if the routes change too often.
+     *
+     * https://stackoverflow.com/questions/44692781/configure-spring-boot-to-redirect-404-to-a-single-page-app
+     *
+     * @param request
+     *        HttpServletRequest
+     * @param response
+     *        HttpServletResponse
+     * @throws IOException
+     *         On error
+     */
+    @RequestMapping(
+        method = {RequestMethod.OPTIONS, RequestMethod.GET}, //
+        path = {"/policy", "/user"})
+    public void forwardAngularRoutes(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        URL url = new URL(request.getScheme(), request.getServerName(), request.getServerPort(), "/index.html");
+        if (logger.isDebugEnabled())
+            logger.debug("forwardAngularRoutes: {} redirected to {}", request.getRequestURI(), url);
+        response.sendRedirect(url.toString());
+    }
 
 }
index 410ad1d..c01c7c6 100644 (file)
  */
 package org.oransc.ric.portal.dashboard.controller;
 
+import io.swagger.annotations.ApiOperation;
+
 import java.lang.invoke.MethodHandles;
 
 import javax.servlet.http.HttpServletResponse;
 
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-import org.oransc.ric.portal.dashboard.DashboardApplication;
 import org.oransc.ric.portal.dashboard.DashboardConstants;
-import org.oransc.ric.portal.dashboard.exceptions.HttpBadRequestException;
-import org.oransc.ric.portal.dashboard.exceptions.HttpInternalServerErrorException;
-import org.oransc.ric.portal.dashboard.exceptions.HttpNotFoundException;
-import org.oransc.ric.portal.dashboard.exceptions.HttpNotImplementedException;
-import org.oransc.ric.portal.dashboard.model.PolicyInstances;
-import org.oransc.ric.portal.dashboard.model.PolicyTypes;
-import org.oransc.ric.portal.dashboard.model.SuccessTransport;
 import org.oransc.ric.portal.dashboard.policyagentapi.PolicyAgentApi;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.annotation.Secured;
 import org.springframework.util.Assert;
 import org.springframework.web.bind.annotation.DeleteMapping;
@@ -51,8 +42,6 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
-import java.util.Collection;
-import io.swagger.annotations.ApiOperation;
 
 /**
  * Proxies calls from the front end to the Policy agent API.
@@ -66,111 +55,85 @@ import io.swagger.annotations.ApiOperation;
 @RequestMapping(value = PolicyController.CONTROLLER_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
 public class PolicyController {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-       private static Gson gson = new GsonBuilder() //
-                       .serializeNulls() //
-                       .create(); //
-
-       // Publish paths in constants so tests are easy to write
-       public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/policy";
-       // Endpoints
-       public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD;
-       public static final String POLICY_TYPES_METHOD = "policytypes";
-       public static final String POLICY_TYPE_ID_NAME = "policy_type_id";
-       public static final String POLICIES_NAME = "policies";
-       public static final String POLICY_INSTANCE_ID_NAME = "policy_instance_id";
-
-       // Populated by the autowired constructor
-       private final PolicyAgentApi policyAgentApi;
-
-       @Autowired
-       public PolicyController(final PolicyAgentApi policyAgentApi) {
-               Assert.notNull(policyAgentApi, "API must not be null");
-               this.policyAgentApi = policyAgentApi;
-               logger.debug("ctor: configured with client type {}", policyAgentApi.getClass().getName());
-       }
-
-       /*
-        * The fields are defined in the Policy Control Typescript interface.
-        */
-       @ApiOperation(value = "Gets the policy types from Near Realtime-RIC")
-       @GetMapping(POLICY_TYPES_METHOD)
-       @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
-       public PolicyTypes getAllPolicyTypes(HttpServletResponse response) {
-               logger.debug("getAllPolicyTypes");
-               return this.policyAgentApi.getAllPolicyTypes();
-       }
-
-       @ApiOperation(value = "Returns the policy instances for the given policy type.")
-       @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME)
-       @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
-       public String getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) {
-               logger.debug("getPolicyInstances {}", policyTypeIdString);
-
-               PolicyInstances i = this.policyAgentApi.getPolicyInstancesForType(policyTypeIdString);
-               String json = gson.toJson(i);
-               return json;
-       }
-
-       @ApiOperation(value = "Returns a policy instance of a type")
-       @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME
-                       + "}")
-       @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
-       public String getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
-                       @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) {
-               logger.debug("getPolicyInstance {}:{}", policyTypeIdString, policyInstanceId);
-               return this.policyAgentApi.getPolicyInstance(policyInstanceId);
-       }
-
-       @ApiOperation(value = "Creates the policy instances for the given policy type.")
-       @PutMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME
-                       + "}")
-       @Secured({ DashboardConstants.ROLE_ADMIN })
-       public void putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
-                       @RequestParam(name = "ric", required = true) String ric,
-                       @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId, @RequestBody String instance) {
-               logger.debug("putPolicyInstance typeId: {}, instanceId: {}, instance: {}", policyTypeIdString, policyInstanceId,
-                               instance);
-               this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance, ric);
-       }
-
-       @ApiOperation(value = "Deletes the policy instances for the given policy type.")
-       @DeleteMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{"
-                       + POLICY_INSTANCE_ID_NAME + "}")
-       @Secured({ DashboardConstants.ROLE_ADMIN })
-       public void deletePolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
-                       @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) {
-               logger.debug("deletePolicyInstance typeId: {}, instanceId: {}", policyTypeIdString, policyInstanceId);
-               this.policyAgentApi.deletePolicy(policyInstanceId);
-       }
-
-       private void checkHttpError(String httpCode) {
-               logger.debug("Http Response Code: {}", httpCode);
-               if (httpCode.equals(String.valueOf(HttpStatus.NOT_FOUND.value()))) {
-                       logger.error("Caught HttpNotFoundException");
-                       throw new HttpNotFoundException("Not Found Exception");
-               } else if (httpCode.equals(String.valueOf(HttpStatus.BAD_REQUEST.value()))) {
-                       logger.error("Caught HttpBadRequestException");
-                       throw new HttpBadRequestException("Bad Request Exception");
-               } else if (httpCode.equals(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()))) {
-                       logger.error("Caught HttpInternalServerErrorException");
-                       throw new HttpInternalServerErrorException("Internal Server Error Exception");
-               } else if (httpCode.equals(String.valueOf(HttpStatus.NOT_IMPLEMENTED.value()))) {
-                       logger.error("Caught HttpNotImplementedException");
-                       throw new HttpNotImplementedException("Not Implemented Exception");
-               }
-       }
-
-       @ApiOperation(value = "Returns the rics supporting the given policy type.")
-       @GetMapping("/rics")
-       @Secured({ DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD })
-       public String getRicsSupportingType(
-                       @RequestParam(name = "policyType", required = true) String supportingPolicyType) {
-               logger.debug("getRicsSupportingType {}", supportingPolicyType);
-
-               Collection<String> result = this.policyAgentApi.getRicsSupportingType(supportingPolicyType);
-               String json = gson.toJson(result);
-               return json;
-       }
-
-};
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    // Publish paths in constants so tests are easy to write
+    public static final String CONTROLLER_PATH = DashboardConstants.ENDPOINT_PREFIX + "/policy";
+    // Endpoints
+    public static final String VERSION_METHOD = DashboardConstants.VERSION_METHOD;
+    public static final String POLICY_TYPES_METHOD = "policytypes";
+    public static final String POLICY_TYPE_ID_NAME = "policy_type_id";
+    public static final String POLICIES_NAME = "policies";
+    public static final String POLICY_INSTANCE_ID_NAME = "policy_instance_id";
+
+    // Populated by the autowired constructor
+    private final PolicyAgentApi policyAgentApi;
+
+    @Autowired
+    public PolicyController(final PolicyAgentApi policyAgentApi) {
+        Assert.notNull(policyAgentApi, "API must not be null");
+        this.policyAgentApi = policyAgentApi;
+        logger.debug("ctor: configured with client type {}", policyAgentApi.getClass().getName());
+    }
+
+    /*
+     * The fields are defined in the Policy Control Typescript interface.
+     */
+    @ApiOperation(value = "Gets the policy types from Near Realtime-RIC")
+    @GetMapping(POLICY_TYPES_METHOD)
+    @Secured({DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD})
+    public ResponseEntity<String> getAllPolicyTypes(HttpServletResponse response) {
+        logger.debug("getAllPolicyTypes");
+        return this.policyAgentApi.getAllPolicyTypes();
+    }
+
+    @ApiOperation(value = "Returns the policy instances for the given policy type.")
+    @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME)
+    @Secured({DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD})
+    public ResponseEntity<String> getPolicyInstances(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString) {
+        logger.debug("getPolicyInstances {}", policyTypeIdString);
+        return this.policyAgentApi.getPolicyInstancesForType(policyTypeIdString);
+    }
+
+    @ApiOperation(value = "Returns a policy instance of a type")
+    @GetMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME
+        + "}")
+    @Secured({DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD})
+    public ResponseEntity<String> getPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
+        @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) {
+        logger.debug("getPolicyInstance {}:{}", policyTypeIdString, policyInstanceId);
+        return this.policyAgentApi.getPolicyInstance(policyInstanceId);
+    }
+
+    @ApiOperation(value = "Creates the policy instances for the given policy type.")
+    @PutMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{" + POLICY_INSTANCE_ID_NAME
+        + "}")
+    @Secured({DashboardConstants.ROLE_ADMIN})
+    public ResponseEntity<String> putPolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
+        @RequestParam(name = "ric", required = true) String ric,
+        @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId, @RequestBody String instance) {
+        logger.debug("putPolicyInstance typeId: {}, instanceId: {}, instance: {}", policyTypeIdString, policyInstanceId,
+            instance);
+        return this.policyAgentApi.putPolicy(policyTypeIdString, policyInstanceId, instance, ric);
+    }
+
+    @ApiOperation(value = "Deletes the policy instances for the given policy type.")
+    @DeleteMapping(POLICY_TYPES_METHOD + "/{" + POLICY_TYPE_ID_NAME + "}/" + POLICIES_NAME + "/{"
+        + POLICY_INSTANCE_ID_NAME + "}")
+    @Secured({DashboardConstants.ROLE_ADMIN})
+    public ResponseEntity<String> deletePolicyInstance(@PathVariable(POLICY_TYPE_ID_NAME) String policyTypeIdString,
+        @PathVariable(POLICY_INSTANCE_ID_NAME) String policyInstanceId) {
+        logger.debug("deletePolicyInstance typeId: {}, instanceId: {}", policyTypeIdString, policyInstanceId);
+        return this.policyAgentApi.deletePolicy(policyInstanceId);
+    }
+
+    @ApiOperation(value = "Returns the rics supporting the given policy type.")
+    @GetMapping("/rics")
+    @Secured({DashboardConstants.ROLE_ADMIN, DashboardConstants.ROLE_STANDARD})
+    public ResponseEntity<String> getRicsSupportingType(
+        @RequestParam(name = "policyType", required = true) String supportingPolicyType) {
+        logger.debug("getRicsSupportingType {}", supportingPolicyType);
+
+        return this.policyAgentApi.getRicsSupportingType(supportingPolicyType);
+    }
+}
index e2248e6..63b78ec 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,7 +35,6 @@ import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.context.request.ServletWebRequest;
-
 import springfox.documentation.annotations.ApiIgnore;
 
 /**
@@ -43,12 +42,12 @@ import springfox.documentation.annotations.ApiIgnore;
  * context, including page not found, and redirects the caller to a custom error
  * page. The caller is also redirected to this page if a REST controller takes
  * an uncaught exception.
- * 
+ *
  * If trace is requested via request parameter ("?trace=true") and available,
  * adds stack trace information to the standard JSON error response.
- * 
+ *
  * Excluded from Swagger API documentation.
- * 
+ *
  * https://stackoverflow.com/questions/25356781/spring-boot-remove-whitelabel-error-page
  * https://www.baeldung.com/spring-boot-custom-error-page
  */
@@ -58,36 +57,36 @@ import springfox.documentation.annotations.ApiIgnore;
 @RequestMapping(value = SimpleErrorController.ERROR_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
 public class SimpleErrorController implements ErrorController {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       public static final String ERROR_PATH = "/error";
+    public static final String ERROR_PATH = "/error";
 
-       private final ErrorAttributes errorAttributes;
+    private final ErrorAttributes errorAttributes;
 
-       @Autowired
-       public SimpleErrorController(ErrorAttributes errorAttributes) {
-               this.errorAttributes = errorAttributes;
-       }
+    @Autowired
+    public SimpleErrorController(ErrorAttributes errorAttributes) {
+        this.errorAttributes = errorAttributes;
+    }
 
-       @Override
-       public String getErrorPath() {
-               logger.warn("getErrorPath");
-               return ERROR_PATH;
-       }
+    @Override
+    public String getErrorPath() {
+        logger.warn("getErrorPath");
+        return ERROR_PATH;
+    }
 
-       @GetMapping
-       public String handleError(HttpServletRequest request) {
-               ServletWebRequest servletWebRequest = new ServletWebRequest(request);
-               Throwable t = errorAttributes.getError(servletWebRequest);
-               if (t != null)
-                       logger.warn("handleError", t);
-               Map<String, Object> attributes = errorAttributes.getErrorAttributes(servletWebRequest, true);
-               attributes.forEach((attribute, value) -> {
-                       logger.warn("handleError: {} -> {}", attribute, value);
-               });
-               // Return the name of the page INCLUDING suffix, which I guess is a "view" name.
-               // Just "error" is not enough, but don't seem to need a ModelAndView object.
-               return "error.html";
-       }
+    @GetMapping
+    public String handleError(HttpServletRequest request) {
+        ServletWebRequest servletWebRequest = new ServletWebRequest(request);
+        Throwable t = errorAttributes.getError(servletWebRequest);
+        if (t != null)
+            logger.warn("handleError", t);
+        Map<String, Object> attributes = errorAttributes.getErrorAttributes(servletWebRequest, true);
+        attributes.forEach((attribute, value) -> {
+            logger.warn("handleError: {} -> {}", attribute, value);
+        });
+        // Return the name of the page INCLUDING suffix, which I guess is a "view" name.
+        // Just "error" is not enough, but don't seem to need a ModelAndView object.
+        return "error.html";
+    }
 
 }
index bcfae62..d3add60 100644 (file)
@@ -34,23 +34,22 @@ import org.springframework.web.util.DefaultUriBuilderFactory;
  */
 public class SimpleKubernetesClient {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       private final String k8sUrl;
-
-       public SimpleKubernetesClient(String baseUrl) {
-               logger.debug("ctor: baseUrl {}", baseUrl);
-               k8sUrl = baseUrl;
-       }
-
-       public String listPods(String namespace) {
-               logger.debug("listPods for namespace {}", namespace);
-               String podsUrl = new DefaultUriBuilderFactory(k8sUrl.trim()).builder().pathSegment("v1")
-                               .pathSegment("namespaces").pathSegment(namespace.trim()).pathSegment("pods").build().normalize()
-                               .toString();
-               RestTemplate rt = new RestTemplate();
-               ResponseEntity<String> podsResponse = rt.getForEntity(podsUrl, String.class);
-               return podsResponse.getBody();
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    private final String k8sUrl;
+
+    public SimpleKubernetesClient(String baseUrl) {
+        logger.debug("ctor: baseUrl {}", baseUrl);
+        k8sUrl = baseUrl;
+    }
+
+    public String listPods(String namespace) {
+        logger.debug("listPods for namespace {}", namespace);
+        String podsUrl = new DefaultUriBuilderFactory(k8sUrl.trim()).builder().pathSegment("v1")
+            .pathSegment("namespaces").pathSegment(namespace.trim()).pathSegment("pods").build().normalize().toString();
+        RestTemplate rt = new RestTemplate();
+        ResponseEntity<String> podsResponse = rt.getForEntity(podsUrl, String.class);
+        return podsResponse.getBody();
+    }
 
 }
index 7bc9f00..3a08206 100644 (file)
@@ -32,54 +32,54 @@ import org.springframework.security.core.userdetails.UserDetails;
 
 public class EcompUserDetails implements UserDetails {
 
-       private static final long serialVersionUID = 1L;
-       private final EcompUser ecompUser;
+    private static final long serialVersionUID = 1L;
+    private final EcompUser ecompUser;
 
-       // This is the default Spring role-name prefix.
-       private static final String ROLEP = "ROLE_";
+    // This is the default Spring role-name prefix.
+    private static final String ROLEP = "ROLE_";
 
-       public EcompUserDetails(EcompUser ecompUser) {
-               this.ecompUser = ecompUser;
-       }
+    public EcompUserDetails(EcompUser ecompUser) {
+        this.ecompUser = ecompUser;
+    }
 
-       /*
-        * Gets a list of authorities (roles) for this user. To keep Spring happy, every
-        * item has prefix ROLE_.
-        */
-       public Collection<? extends GrantedAuthority> getAuthorities() {
-               List<GrantedAuthority> roleList = new ArrayList<>();
-               Iterator<EcompRole> roleIter = ecompUser.getRoles().iterator();
-               while (roleIter.hasNext()) {
-                       EcompRole role = roleIter.next();
-                       // Add the prefix if the ONAP portal doesn't supply it.
-                       final String roleName = role.getName().startsWith(ROLEP) ? role.getName() : ROLEP + role.getName();
-                       roleList.add(new SimpleGrantedAuthority(roleName));
-               }
-               return roleList;
-       }
+    /*
+     * Gets a list of authorities (roles) for this user. To keep Spring happy, every
+     * item has prefix ROLE_.
+     */
+    public Collection<? extends GrantedAuthority> getAuthorities() {
+        List<GrantedAuthority> roleList = new ArrayList<>();
+        Iterator<EcompRole> roleIter = ecompUser.getRoles().iterator();
+        while (roleIter.hasNext()) {
+            EcompRole role = roleIter.next();
+            // Add the prefix if the ONAP portal doesn't supply it.
+            final String roleName = role.getName().startsWith(ROLEP) ? role.getName() : ROLEP + role.getName();
+            roleList.add(new SimpleGrantedAuthority(roleName));
+        }
+        return roleList;
+    }
 
-       public String getPassword() {
-               return null;
-       }
+    public String getPassword() {
+        return null;
+    }
 
-       public String getUsername() {
-               return ecompUser.getLoginId();
-       }
+    public String getUsername() {
+        return ecompUser.getLoginId();
+    }
 
-       public boolean isAccountNonExpired() {
-               return true;
-       }
+    public boolean isAccountNonExpired() {
+        return true;
+    }
 
-       public boolean isAccountNonLocked() {
-               return true;
-       }
+    public boolean isAccountNonLocked() {
+        return true;
+    }
 
-       public boolean isCredentialsNonExpired() {
-               return true;
-       }
+    public boolean isCredentialsNonExpired() {
+        return true;
+    }
 
-       public boolean isEnabled() {
-               return ecompUser.isActive();
-       }
+    public boolean isEnabled() {
+        return ecompUser.isActive();
+    }
 
 }
index 516e3c8..f1250c1 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,106 +28,106 @@ import java.time.Instant;
  */
 public class ErrorTransport implements IDashboardResponse {
 
-       private Instant timestamp;
-       private Integer status;
-       private String error;
-       private String message;
-       private String path;
-
-       /**
-        * Builds an empty object.
-        */
-       public ErrorTransport() {
-               // no-arg constructor
-       }
-
-       /**
-        * Convenience constructor for minimal value set.
-        * 
-        * @param status
-        *                   Integer value like 400
-        * @param error
-        *                   Error message
-        */
-       public ErrorTransport(int status, String error) {
-               this(status, error, null, null);
-       }
-
-       /**
-        * Convenience constructor for populating an error from an exception
-        * 
-        * @param status
-        *                      Integer value like 400
-        * @param throwable
-        *                      The caught exception/throwable to convert to String with
-        *                      an upper bound on characters
-        */
-       public ErrorTransport(int status, Throwable throwable) {
-               this.timestamp = Instant.now();
-               this.status = status;
-               final int enough = 256;
-               String exString = throwable.toString();
-               this.error = exString.length() > enough ? exString.substring(0, enough) : exString;
-       }
-
-       /**
-        * Builds an object with all fields
-        * 
-        * @param status
-        *                    Integer value like 500
-        * @param error
-        *                    Explanation
-        * @param message
-        *                    Additional explanation
-        * @param path
-        *                    Requested path
-        */
-       public ErrorTransport(int status, String error, String message, String path) {
-               this.timestamp = Instant.now();
-               this.status = status;
-               this.error = error;
-               this.message = message;
-               this.path = path;
-       }
-
-       public Integer getStatus() {
-               return status;
-       }
-
-       public void setStatus(Integer status) {
-               this.status = status;
-       }
-
-       public String getMessage() {
-               return message;
-       }
-
-       public void setMessage(String error) {
-               this.message = error;
-       }
-
-       public Instant getTimestamp() {
-               return timestamp;
-       }
-
-       public void setTimestamp(Instant timestamp) {
-               this.timestamp = timestamp;
-       }
-
-       public String getError() {
-               return error;
-       }
-
-       public void setError(String error) {
-               this.error = error;
-       }
-
-       public String getPath() {
-               return path;
-       }
-
-       public void setPath(String path) {
-               this.path = path;
-       }
+    private Instant timestamp;
+    private Integer status;
+    private String error;
+    private String message;
+    private String path;
+
+    /**
+     * Builds an empty object.
+     */
+    public ErrorTransport() {
+        // no-arg constructor
+    }
+
+    /**
+     * Convenience constructor for minimal value set.
+     *
+     * @param status
+     *        Integer value like 400
+     * @param error
+     *        Error message
+     */
+    public ErrorTransport(int status, String error) {
+        this(status, error, null, null);
+    }
+
+    /**
+     * Convenience constructor for populating an error from an exception
+     *
+     * @param status
+     *        Integer value like 400
+     * @param throwable
+     *        The caught exception/throwable to convert to String with
+     *        an upper bound on characters
+     */
+    public ErrorTransport(int status, Throwable throwable) {
+        this.timestamp = Instant.now();
+        this.status = status;
+        final int enough = 256;
+        String exString = throwable.toString();
+        this.error = exString.length() > enough ? exString.substring(0, enough) : exString;
+    }
+
+    /**
+     * Builds an object with all fields
+     *
+     * @param status
+     *        Integer value like 500
+     * @param error
+     *        Explanation
+     * @param message
+     *        Additional explanation
+     * @param path
+     *        Requested path
+     */
+    public ErrorTransport(int status, String error, String message, String path) {
+        this.timestamp = Instant.now();
+        this.status = status;
+        this.error = error;
+        this.message = message;
+        this.path = path;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String error) {
+        this.message = error;
+    }
+
+    public Instant getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Instant timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public void setError(String error) {
+        this.error = error;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
 
 }
index ca1b79d..30cfd2a 100644 (file)
@@ -26,16 +26,16 @@ import org.immutables.value.Value;
 @Gson.TypeAdapters
 public interface PolicyInfo {
 
-       public String id();
+    public String id();
 
-       public String type();
+    public String type();
 
-       public String ric();
+    public String ric();
 
-       public String json();
+    public String json();
 
-       public String service();
+    public String service();
 
-       public String lastModified();
+    public String lastModified();
 
 }
index eb6b455..c6faf9b 100644 (file)
@@ -23,6 +23,6 @@ import java.util.ArrayList;
 
 public class PolicyInstances extends ArrayList<PolicyInfo> {
 
-       private static final long serialVersionUID = -928428052502491021L;
+    private static final long serialVersionUID = -928428052502491021L;
 
 }
index ea51cc5..f0ca285 100644 (file)
@@ -23,35 +23,35 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 
 public class PolicyType {
 
-       @JsonProperty("name")
-       String name;
+    @JsonProperty("name")
+    String name;
 
-       @JsonProperty("schema")
-       String schema;
+    @JsonProperty("schema")
+    String schema;
 
-       public PolicyType(String name, String schema) {
-               this.name = name;
-               this.schema = schema;
-       }
+    public PolicyType(String name, String schema) {
+        this.name = name;
+        this.schema = schema;
+    }
 
-       public String getName() {
-               return name;
-       }
+    public String getName() {
+        return name;
+    }
 
-       public void setName(String name) {
-               this.name = name;
-       }
+    public void setName(String name) {
+        this.name = name;
+    }
 
-       public String getSchema() {
-               return schema;
-       }
+    public String getSchema() {
+        return schema;
+    }
 
-       public void setSchema(String schema) {
-               this.schema = schema;
-       }
+    public void setSchema(String schema) {
+        this.schema = schema;
+    }
 
-       @Override
-       public String toString() {
-               return "[name:" + name + ", schema:" + schema + "]";
-       }
+    @Override
+    public String toString() {
+        return "[name:" + name + ", schema:" + schema + "]";
+    }
 }
index 3165d1b..43a6383 100644 (file)
@@ -23,6 +23,6 @@ import java.util.ArrayList;
 
 public class PolicyTypes extends ArrayList<PolicyType> {
 
-       private static final long serialVersionUID = -928428052502491021L;
+    private static final long serialVersionUID = -928428052502491021L;
 
 }
index 9e13789..65b39eb 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,43 +21,43 @@ package org.oransc.ric.portal.dashboard.model;
 
 public class SuccessTransport implements IDashboardResponse {
 
-       private int status;
-       private Object data;
-
-       /**
-        * Builds an empty object
-        */
-       public SuccessTransport() {
-               // no-arg constructor
-       }
-
-       /**
-        * Builds an object with the specified values.
-        * 
-        * @param status
-        *                   Status code
-        * @param data
-        *                   Data to transport
-        */
-       public SuccessTransport(int status, Object data) {
-               this.status = status;
-               this.data = data;
-       }
-
-       public int getStatus() {
-               return status;
-       }
-
-       public void setStatus(int status) {
-               this.status = status;
-       }
-
-       public Object getData() {
-               return data;
-       }
-
-       public void setData(Object data) {
-               this.data = data;
-       }
+    private int status;
+    private Object data;
+
+    /**
+     * Builds an empty object
+     */
+    public SuccessTransport() {
+        // no-arg constructor
+    }
+
+    /**
+     * Builds an object with the specified values.
+     *
+     * @param status
+     *        Status code
+     * @param data
+     *        Data to transport
+     */
+    public SuccessTransport(int status, Object data) {
+        this.status = status;
+        this.data = data;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
 
 }
index 144a77a..ff254d2 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  */
 package org.oransc.ric.portal.dashboard.policyagentapi;
 
-import java.util.Collection;
-
-import org.oransc.ric.portal.dashboard.model.PolicyInstances;
-import org.oransc.ric.portal.dashboard.model.PolicyTypes;
-import org.springframework.web.client.RestClientException;
+import org.springframework.http.ResponseEntity;
 
 public interface PolicyAgentApi {
 
-    public PolicyTypes getAllPolicyTypes() throws RestClientException;
+    public ResponseEntity<String> getAllPolicyTypes();
 
-    public PolicyInstances getPolicyInstancesForType(String type);
+    public ResponseEntity<String> getPolicyInstancesForType(String type);
 
-    public String getPolicyInstance(String id) throws RestClientException;
+    public ResponseEntity<String> getPolicyInstance(String id);
 
-    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
-            throws RestClientException;
+    public ResponseEntity<String> putPolicy(String policyTypeIdString, String policyInstanceId, String json,
+        String ric);
 
-    public void deletePolicy(String policyInstanceId) throws RestClientException;
+    public ResponseEntity<String> deletePolicy(String policyInstanceId);
 
-    public Collection<String> getRicsSupportingType(String typeName);
+    public ResponseEntity<String> getRicsSupportingType(String typeName);
 
 }
index d83023b..c661e66 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  */
 package org.oransc.ric.portal.dashboard.policyagentapi;
 
-import org.oransc.ric.portal.dashboard.DashboardConstants;
-import org.oransc.ric.portal.dashboard.model.ImmutablePolicyInfo;
-import org.oransc.ric.portal.dashboard.model.PolicyInfo;
-import org.oransc.ric.portal.dashboard.model.PolicyInstances;
-import org.oransc.ric.portal.dashboard.model.PolicyType;
-import org.oransc.ric.portal.dashboard.model.PolicyTypes;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import org.springframework.stereotype.Component;
-import org.springframework.web.client.RestClientException;
-import org.springframework.web.client.RestTemplate;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Type;
-
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
-import com.google.gson.annotations.SerializedName;
 import com.google.gson.reflect.TypeToken;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
 import org.immutables.gson.Gson;
 import org.immutables.value.Value;
+import org.oransc.ric.portal.dashboard.model.ImmutablePolicyInfo;
+import org.oransc.ric.portal.dashboard.model.PolicyInfo;
+import org.oransc.ric.portal.dashboard.model.PolicyInstances;
+import org.oransc.ric.portal.dashboard.model.PolicyType;
+import org.oransc.ric.portal.dashboard.model.PolicyTypes;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
 
 @Component("PolicyAgentApi")
 public class PolicyAgentApiImpl implements PolicyAgentApi {
@@ -58,14 +55,14 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
     RestTemplate restTemplate = new RestTemplate();
 
     private static com.google.gson.Gson gson = new GsonBuilder() //
-            .serializeNulls() //
-            .create(); //
+        .serializeNulls() //
+        .create(); //
 
     private final String urlPrefix;
 
     @Autowired
     public PolicyAgentApiImpl(
-            @org.springframework.beans.factory.annotation.Value("${policycontroller.url.prefix}") final String urlPrefix) {
+        @org.springframework.beans.factory.annotation.Value("${policycontroller.url.prefix}") final String urlPrefix) {
         logger.debug("ctor prefix '{}'", urlPrefix);
         this.urlPrefix = urlPrefix;
     }
@@ -84,66 +81,89 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
     }
 
     @Override
-    public PolicyTypes getAllPolicyTypes() throws RestClientException {
+    public ResponseEntity<String> getAllPolicyTypes() {
         String url = baseUrl() + "/policy_schemas";
-        String rsp = this.restTemplate.getForObject(url, String.class);
+        ResponseEntity<String> rsp = this.restTemplate.getForEntity(url, String.class);
+        if (!rsp.getStatusCode().is2xxSuccessful()) {
+            return rsp;
+        }
 
         PolicyTypes result = new PolicyTypes();
         JsonParser jsonParser = new JsonParser();
-        JsonArray schemas = jsonParser.parse(rsp).getAsJsonArray();
-        for (JsonElement schema : schemas) {
-            JsonObject schemaObj = schema.getAsJsonObject();
-            String title = schemaObj.get("title").getAsString();
-            String schemaAsStr = schemaObj.toString();
-            PolicyType pt = new PolicyType(title, schemaAsStr);
-            result.add(pt);
+        try {
+            JsonArray schemas = jsonParser.parse(rsp.getBody()).getAsJsonArray();
+            for (JsonElement schema : schemas) {
+                JsonObject schemaObj = schema.getAsJsonObject();
+                String title = schemaObj.get("title").getAsString();
+                String schemaAsStr = schemaObj.toString();
+                PolicyType pt = new PolicyType(title, schemaAsStr);
+                result.add(pt);
+            }
+            return new ResponseEntity<>(gson.toJson(result), rsp.getStatusCode());
+        } catch (Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
         }
-        return result;
     }
 
     @Override
-    public PolicyInstances getPolicyInstancesForType(String type) {
+    public ResponseEntity<String> getPolicyInstancesForType(String type) {
         String url = baseUrl() + "/policies?type={type}";
         Map<String, ?> uriVariables = Map.of("type", type);
-        String rsp = this.restTemplate.getForObject(url, String.class, uriVariables);
-
-        Type listType = new TypeToken<List<ImmutablePolicyInfo>>() {
-        }.getType();
-        List<PolicyInfo> rspParsed = gson.fromJson(rsp, listType);
+        ResponseEntity<String> rsp = this.restTemplate.getForEntity(url, String.class, uriVariables);
+        if (!rsp.getStatusCode().is2xxSuccessful()) {
+            return rsp;
+        }
 
-        PolicyInstances result = new PolicyInstances();
-        for (PolicyInfo p : rspParsed) {
-            result.add(p);
+        try {
+            Type listType = new TypeToken<List<ImmutablePolicyInfo>>() {}.getType();
+            List<PolicyInfo> rspParsed = gson.fromJson(rsp.getBody(), listType);
+            PolicyInstances result = new PolicyInstances();
+            for (PolicyInfo p : rspParsed) {
+                result.add(p);
+            }
+            return new ResponseEntity<>(gson.toJson(result), rsp.getStatusCode());
+        } catch (Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
         }
-        return result;
     }
 
     @Override
-    public String getPolicyInstance(String id) throws RestClientException {
+    public ResponseEntity<String> getPolicyInstance(String id) {
         String url = baseUrl() + "/policy?instance={id}";
         Map<String, ?> uriVariables = Map.of("id", id);
 
-        return this.restTemplate.getForObject(url, String.class, uriVariables);
+        return this.restTemplate.getForEntity(url, String.class, uriVariables);
     }
 
     @Override
-    public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
-            throws RestClientException {
+    public ResponseEntity<String> putPolicy(String policyTypeIdString, String policyInstanceId, String json,
+        String ric) {
         String url = baseUrl() + "/policy?type={type}&instance={instance}&ric={ric}&service={service}";
         Map<String, ?> uriVariables = Map.of( //
-                "type", policyTypeIdString, //
-                "instance", policyInstanceId, //
-                "ric", ric, //
-                "service", "dashboard");
-
-        this.restTemplate.put(url, json, uriVariables);
+            "type", policyTypeIdString, //
+            "instance", policyInstanceId, //
+            "ric", ric, //
+            "service", "dashboard");
+
+        try {
+            this.restTemplate.put(url, json, uriVariables);
+            return new ResponseEntity<>("Policy was put successfully", HttpStatus.OK);
+        } catch (Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
+        }
     }
 
     @Override
-    public void deletePolicy(String policyInstanceId) throws RestClientException {
+    public ResponseEntity<String> deletePolicy(String policyInstanceId) {
         String url = baseUrl() + "/policy?instance={instance}";
         Map<String, ?> uriVariables = Map.of("instance", policyInstanceId);
-        this.restTemplate.delete(url, uriVariables);
+        try {
+            this.restTemplate.delete(url, uriVariables);
+            return new ResponseEntity<>("Policy was deleted successfully", HttpStatus.NO_CONTENT);
+        } catch (Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
+        }
+
     }
 
     @Value.Immutable
@@ -157,20 +177,22 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
     }
 
     @Override
-    public Collection<String> getRicsSupportingType(String typeName) {
+    public ResponseEntity<String> getRicsSupportingType(String typeName) {
         String url = baseUrl() + "/rics?policyType={typeName}";
         Map<String, ?> uriVariables = Map.of("typeName", typeName);
         String rsp = this.restTemplate.getForObject(url, String.class, uriVariables);
 
-        Type listType = new TypeToken<List<ImmutableRicInfo>>() {
-        }.getType();
-        List<RicInfo> rspParsed = gson.fromJson(rsp, listType);
-
-        Collection<String> result = new Vector<>(rspParsed.size());
-        for (RicInfo ric : rspParsed) {
-            result.add(ric.name());
+        try {
+            Type listType = new TypeToken<List<ImmutableRicInfo>>() {}.getType();
+            List<RicInfo> rspParsed = gson.fromJson(rsp, listType);
+            Collection<String> result = new Vector<>(rspParsed.size());
+            for (RicInfo ric : rspParsed) {
+                result.add(ric.name());
+            }
+            return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
+        } catch (Exception e) {
+            return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
         }
-        return result;
     }
 
 }
index 34d80c9..552d783 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -27,15 +27,15 @@ import org.onap.portalsdk.core.onboarding.exception.CipherUtilException;
  */
 public interface IPortalSdkDecryptor {
 
-       /**
-        * Decrypts the specified value using a known key.
-        * 
-        * @param cipherText
-        *                       Encrypted value
-        * @return Clear text on success, null otherwise.
-        * @throws CipherUtilException
-        *                                 if any decryption step fails
-        */
-       String decrypt(String cipherText) throws CipherUtilException;
+    /**
+     * Decrypts the specified value using a known key.
+     *
+     * @param cipherText
+     *        Encrypted value
+     * @return Clear text on success, null otherwise.
+     * @throws CipherUtilException
+     *         if any decryption step fails
+     */
+    String decrypt(String cipherText) throws CipherUtilException;
 
 }
index dc70f7e..f4daa5c 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -38,83 +38,83 @@ import org.slf4j.LoggerFactory;
  */
 public class PortalAuthManager {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       final Map<String, String> credentialsMap;
-       private final IPortalSdkDecryptor portalSdkDecryptor;
-       private final String userIdCookieName;
+    final Map<String, String> credentialsMap;
+    private final IPortalSdkDecryptor portalSdkDecryptor;
+    private final String userIdCookieName;
 
-       public PortalAuthManager(final String appName, final String username, final String password,
-                       final String decryptorClassName, final String userCookie)
-                       throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
-                       InvocationTargetException, NoSuchMethodException, SecurityException {
-               credentialsMap = new HashMap<>();
-               credentialsMap.put(IPortalRestCentralService.CREDENTIALS_APP, appName);
-               credentialsMap.put(IPortalRestCentralService.CREDENTIALS_USER, username);
-               credentialsMap.put(IPortalRestCentralService.CREDENTIALS_PASS, password);
-               this.userIdCookieName = userCookie;
-               // Instantiate here so configuration errors are detected at app-start time
-               logger.debug("ctor: using decryptor class {}", decryptorClassName);
-               Class<?> decryptorClass = Class.forName(decryptorClassName);
-               portalSdkDecryptor = (IPortalSdkDecryptor) decryptorClass.getDeclaredConstructor().newInstance();
-       }
+    public PortalAuthManager(final String appName, final String username, final String password,
+        final String decryptorClassName, final String userCookie)
+        throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
+        InvocationTargetException, NoSuchMethodException, SecurityException {
+        credentialsMap = new HashMap<>();
+        credentialsMap.put(IPortalRestCentralService.CREDENTIALS_APP, appName);
+        credentialsMap.put(IPortalRestCentralService.CREDENTIALS_USER, username);
+        credentialsMap.put(IPortalRestCentralService.CREDENTIALS_PASS, password);
+        this.userIdCookieName = userCookie;
+        // Instantiate here so configuration errors are detected at app-start time
+        logger.debug("ctor: using decryptor class {}", decryptorClassName);
+        Class<?> decryptorClass = Class.forName(decryptorClassName);
+        portalSdkDecryptor = (IPortalSdkDecryptor) decryptorClass.getDeclaredConstructor().newInstance();
+    }
 
-       /**
-        * @return A map of key-value pairs with application name, user name and
-        *         password.
-        */
-       public Map<String, String> getAppCredentials() {
-               return credentialsMap;
-       }
+    /**
+     * @return A map of key-value pairs with application name, user name and
+     *         password.
+     */
+    public Map<String, String> getAppCredentials() {
+        return credentialsMap;
+    }
 
-       /**
-        * Searches the request for a cookie with the specified name.
-        *
-        * @param request
-        *                       HttpServletRequest
-        * @param cookieName
-        *                       Cookie name
-        * @return Cookie, or null if not found.
-        */
-       private Cookie getCookie(HttpServletRequest request, String cookieName) {
-               Cookie[] cookies = request.getCookies();
-               if (cookies != null)
-                       for (Cookie cookie : cookies)
-                               if (cookie.getName().equals(cookieName))
-                                       return cookie;
-               return null;
-       }
+    /**
+     * Searches the request for a cookie with the specified name.
+     *
+     * @param request
+     *        HttpServletRequest
+     * @param cookieName
+     *        Cookie name
+     * @return Cookie, or null if not found.
+     */
+    private Cookie getCookie(HttpServletRequest request, String cookieName) {
+        Cookie[] cookies = request.getCookies();
+        if (cookies != null)
+            for (Cookie cookie : cookies)
+                if (cookie.getName().equals(cookieName))
+                    return cookie;
+        return null;
+    }
 
-       /**
-        * Validates whether the ECOMP Portal sign-on process has completed. Checks for
-        * the ECOMP cookie first, then the user cookie.
-        * 
-        * @param request
-        *                    HttpServletRequest
-        * @return User ID if the ECOMP cookie is present and the sign-on process
-        *         established a user ID; else null.
-        */
-       public String validateEcompSso(HttpServletRequest request) {
-               // Check ECOMP Portal cookie
-               Cookie ep = getCookie(request, PortalApiConstants.EP_SERVICE);
-               if (ep == null) {
-                       logger.debug("validateEcompSso: cookie not found: {}", PortalApiConstants.EP_SERVICE);
-                       return null;
-               }
-               logger.trace("validateEcompSso: found cookie {}", PortalApiConstants.EP_SERVICE);
-               Cookie user = getCookie(request, userIdCookieName);
-               if (user == null) {
-                       logger.debug("validateEcompSso: cookie not found: {}", userIdCookieName);
-                       return null;
-               }
-               logger.trace("validateEcompSso: user cookie {}", userIdCookieName);
-               String userid = null;
-               try {
-                       userid = portalSdkDecryptor.decrypt(user.getValue());
-               } catch (CipherUtilException e) {
-                       throw new IllegalArgumentException("validateEcompSso failed", e);
-               }
-               return userid;
-       }
+    /**
+     * Validates whether the ECOMP Portal sign-on process has completed. Checks for
+     * the ECOMP cookie first, then the user cookie.
+     *
+     * @param request
+     *        HttpServletRequest
+     * @return User ID if the ECOMP cookie is present and the sign-on process
+     *         established a user ID; else null.
+     */
+    public String validateEcompSso(HttpServletRequest request) {
+        // Check ECOMP Portal cookie
+        Cookie ep = getCookie(request, PortalApiConstants.EP_SERVICE);
+        if (ep == null) {
+            logger.debug("validateEcompSso: cookie not found: {}", PortalApiConstants.EP_SERVICE);
+            return null;
+        }
+        logger.trace("validateEcompSso: found cookie {}", PortalApiConstants.EP_SERVICE);
+        Cookie user = getCookie(request, userIdCookieName);
+        if (user == null) {
+            logger.debug("validateEcompSso: cookie not found: {}", userIdCookieName);
+            return null;
+        }
+        logger.trace("validateEcompSso: user cookie {}", userIdCookieName);
+        String userid = null;
+        try {
+            userid = portalSdkDecryptor.decrypt(user.getValue());
+        } catch (CipherUtilException e) {
+            throw new IllegalArgumentException("validateEcompSso failed", e);
+        }
+        return userid;
+    }
 
 }
index 4b6de91..711761a 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -71,211 +71,211 @@ import org.springframework.security.web.authentication.preauth.PreAuthenticatedA
  * Portal knows where to forward the request to once the Portal Session is
  * created and EPService cookie is set.
  * </UL>
- * 
+ *
  * TODO: What about sessions? Will this be stateless?
- * 
+ *
  * This filter uses no annotations to avoid Spring's automatic registration,
  * which add this filter in the chain in the wrong order.
  */
 public class PortalAuthenticationFilter implements Filter {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       // Unfortunately not all file names are defined as constants
-       private static final String[] securityPropertyFiles = { KeyProperties.PROPERTY_FILE_NAME,
-                       PortalApiProperties.PROPERTY_FILE_NAME, DefaultSecurityConfiguration.DEFAULT_RESOURCE_FILE,
-                       "validation.properties" };
+    // Unfortunately not all file names are defined as constants
+    private static final String[] securityPropertyFiles =
+        {KeyProperties.PROPERTY_FILE_NAME, PortalApiProperties.PROPERTY_FILE_NAME,
+            DefaultSecurityConfiguration.DEFAULT_RESOURCE_FILE, "validation.properties"};
 
-       public static final String REDIRECT_URL_KEY = "redirectUrl";
+    public static final String REDIRECT_URL_KEY = "redirectUrl";
 
-       private final boolean enforcePortalSecurity;
-       private final PortalAuthManager authManager;
+    private final boolean enforcePortalSecurity;
+    private final PortalAuthManager authManager;
 
-       private final DashboardUserManager userManager;
+    private final DashboardUserManager userManager;
 
-       public PortalAuthenticationFilter(boolean portalSecurity, PortalAuthManager authManager,
-                       DashboardUserManager userManager) {
-               this.enforcePortalSecurity = portalSecurity;
-               this.authManager = authManager;
-               this.userManager = userManager;
-               if (portalSecurity) {
-                       // Throw if security is requested and prerequisites are not met
-                       for (String pf : securityPropertyFiles) {
-                               InputStream in = MethodHandles.lookup().lookupClass().getClassLoader().getResourceAsStream(pf);
-                               if (in == null) {
-                                       String msg = "Failed to find property file on classpath: " + pf;
-                                       logger.error(msg);
-                                       throw new RuntimeException(msg);
-                               } else {
-                                       try {
-                                               in.close();
-                                       } catch (IOException ex) {
-                                               logger.warn("Failed to close stream", ex);
-                                       }
-                               }
-                       }
-               }
-       }
+    public PortalAuthenticationFilter(boolean portalSecurity, PortalAuthManager authManager,
+        DashboardUserManager userManager) {
+        this.enforcePortalSecurity = portalSecurity;
+        this.authManager = authManager;
+        this.userManager = userManager;
+        if (portalSecurity) {
+            // Throw if security is requested and prerequisites are not met
+            for (String pf : securityPropertyFiles) {
+                InputStream in = MethodHandles.lookup().lookupClass().getClassLoader().getResourceAsStream(pf);
+                if (in == null) {
+                    String msg = "Failed to find property file on classpath: " + pf;
+                    logger.error(msg);
+                    throw new RuntimeException(msg);
+                } else {
+                    try {
+                        in.close();
+                    } catch (IOException ex) {
+                        logger.warn("Failed to close stream", ex);
+                    }
+                }
+            }
+        }
+    }
 
-       @Override
-       public void init(FilterConfig filterConfig) throws ServletException {
-               // complain loudly if this key property is missing
-               String url = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
-               logger.debug("init: Portal redirect URL {}", url);
-               if (url == null)
-                       logger.error(
-                                       "init: Failed to find property in portal.properties: " + PortalApiConstants.ECOMP_REDIRECT_URL);
-       }
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        // complain loudly if this key property is missing
+        String url = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
+        logger.debug("init: Portal redirect URL {}", url);
+        if (url == null)
+            logger
+                .error("init: Failed to find property in portal.properties: " + PortalApiConstants.ECOMP_REDIRECT_URL);
+    }
 
-       @Override
-       public void destroy() {
-               // No resources to release
-       }
+    @Override
+    public void destroy() {
+        // No resources to release
+    }
 
-       /**
-        * Requests for pages ignored in the web security config do not hit this filter.
-        */
-       @Override
-       public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
-                       throws IOException, ServletException {
-               if (enforcePortalSecurity)
-                       doFilterEPSDKFW(req, res, chain);
-               else
-                       doFilterMockUserAdminRole(req, res, chain);
-       }
+    /**
+     * Requests for pages ignored in the web security config do not hit this filter.
+     */
+    @Override
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
+        throws IOException, ServletException {
+        if (enforcePortalSecurity)
+            doFilterEPSDKFW(req, res, chain);
+        else
+            doFilterMockUserAdminRole(req, res, chain);
+    }
 
-       /*
-        * Populates security context with a mock user in the admin role.
-        * 
-        */
-       private void doFilterMockUserAdminRole(ServletRequest req, ServletResponse res, FilterChain chain)
-                       throws IOException, ServletException {
-               Authentication auth = SecurityContextHolder.getContext().getAuthentication();
-               if (auth == null || auth.getAuthorities().isEmpty()) {
-                       if (logger.isDebugEnabled()) {
-                               logger.debug("doFilter adding auth to request URI {}",
-                                               (req instanceof HttpServletRequest) ? ((HttpServletRequest) req).getRequestURL() : req);
-                       }
-                       EcompRole admin = new EcompRole();
-                       admin.setId(1L);
-                       admin.setName(DashboardConstants.ROLE_ADMIN);
-                       HashSet<EcompRole> roles = new HashSet<>();
-                       roles.add(admin);
-                       EcompUser user = new EcompUser();
-                       user.setLoginId("fakeLoginId");
-                       user.setRoles(roles);
-                       user.setActive(true);
-                       EcompUserDetails userDetails = new EcompUserDetails(user);
-                       PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(userDetails,
-                                       "fakeCredentials", userDetails.getAuthorities());
-                       SecurityContextHolder.getContext().setAuthentication(authToken);
-               } else {
-                       logger.debug("doFilter: authorities {}", auth.getAuthorities());
-               }
-               chain.doFilter(req, res);
-       }
+    /*
+     * Populates security context with a mock user in the admin role.
+     *
+     */
+    private void doFilterMockUserAdminRole(ServletRequest req, ServletResponse res, FilterChain chain)
+        throws IOException, ServletException {
+        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
+        if (auth == null || auth.getAuthorities().isEmpty()) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("doFilter adding auth to request URI {}",
+                    (req instanceof HttpServletRequest) ? ((HttpServletRequest) req).getRequestURL() : req);
+            }
+            EcompRole admin = new EcompRole();
+            admin.setId(1L);
+            admin.setName(DashboardConstants.ROLE_ADMIN);
+            HashSet<EcompRole> roles = new HashSet<>();
+            roles.add(admin);
+            EcompUser user = new EcompUser();
+            user.setLoginId("fakeLoginId");
+            user.setRoles(roles);
+            user.setActive(true);
+            EcompUserDetails userDetails = new EcompUserDetails(user);
+            PreAuthenticatedAuthenticationToken authToken =
+                new PreAuthenticatedAuthenticationToken(userDetails, "fakeCredentials", userDetails.getAuthorities());
+            SecurityContextHolder.getContext().setAuthentication(authToken);
+        } else {
+            logger.debug("doFilter: authorities {}", auth.getAuthorities());
+        }
+        chain.doFilter(req, res);
+    }
 
-       /*
-        * Checks for valid cookies and allows request to be served if found; redirects
-        * to Portal otherwise.
-        */
-       private void doFilterEPSDKFW(ServletRequest req, ServletResponse res, FilterChain chain)
-                       throws IOException, ServletException {
-               HttpServletRequest request = (HttpServletRequest) req;
-               HttpServletResponse response = (HttpServletResponse) res;
-               if (logger.isTraceEnabled())
-                       logger.trace("doFilter: req {}", request.getRequestURI());
-               // Need to authenticate the request
-               final String userId = authManager.validateEcompSso(request);
-               final EcompUser ecompUser = (userId == null ? null : userManager.getUser(userId));
-               if (userId == null || ecompUser == null) {
-                       logger.debug("doFilter: unauthorized user requests URI {}, serving login page", request.getRequestURI());
-                       StringBuffer sb = request.getRequestURL();
-                       sb.append(request.getQueryString() == null ? "" : "?" + request.getQueryString());
-                       String body = generateLoginRedirectPage(sb.toString());
-                       response.setContentType(MediaType.TEXT_HTML_VALUE);
-                       response.getWriter().print(body);
-                       response.getWriter().flush();
-               } else {
-                       EcompUserDetails userDetails = new EcompUserDetails(ecompUser);
-                       // Using portal session as credentials is a hack
-                       PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(userDetails,
-                                       getPortalSessionId(request), userDetails.getAuthorities());
-                       SecurityContextHolder.getContext().setAuthentication(authToken);
-                       // Pass request back down the filter chain
-                       chain.doFilter(request, response);
-               }
-       }
+    /*
+     * Checks for valid cookies and allows request to be served if found; redirects
+     * to Portal otherwise.
+     */
+    private void doFilterEPSDKFW(ServletRequest req, ServletResponse res, FilterChain chain)
+        throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) res;
+        if (logger.isTraceEnabled())
+            logger.trace("doFilter: req {}", request.getRequestURI());
+        // Need to authenticate the request
+        final String userId = authManager.validateEcompSso(request);
+        final EcompUser ecompUser = (userId == null ? null : userManager.getUser(userId));
+        if (userId == null || ecompUser == null) {
+            logger.debug("doFilter: unauthorized user requests URI {}, serving login page", request.getRequestURI());
+            StringBuffer sb = request.getRequestURL();
+            sb.append(request.getQueryString() == null ? "" : "?" + request.getQueryString());
+            String body = generateLoginRedirectPage(sb.toString());
+            response.setContentType(MediaType.TEXT_HTML_VALUE);
+            response.getWriter().print(body);
+            response.getWriter().flush();
+        } else {
+            EcompUserDetails userDetails = new EcompUserDetails(ecompUser);
+            // Using portal session as credentials is a hack
+            PreAuthenticatedAuthenticationToken authToken = new PreAuthenticatedAuthenticationToken(userDetails,
+                getPortalSessionId(request), userDetails.getAuthorities());
+            SecurityContextHolder.getContext().setAuthentication(authToken);
+            // Pass request back down the filter chain
+            chain.doFilter(request, response);
+        }
+    }
 
-       /**
-        * Generates a page with text only, absolutely no references to any webapp
-        * resources, so this can be served to an unauthenticated user without
-        * triggering a new authentication attempt. The page has a link to the Portal
-        * URL from configuration, with a return URL that is the original request.
-        * 
-        * @param appUrl
-        *                   Original requested URL
-        * @return HTML
-        * @throws UnsupportedEncodingException
-        *                                          On error
-        */
-       private static String generateLoginRedirectPage(String appUrl) throws UnsupportedEncodingException {
-               String encodedAppUrl = URLEncoder.encode(appUrl, "UTF-8");
-               String portalBaseUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
-               String redirectUrl = portalBaseUrl + "?" + PortalAuthenticationFilter.REDIRECT_URL_KEY + "=" + encodedAppUrl;
-               String aHref = "<a href=\"" + redirectUrl + "\">";
-               // If only Java had "here" documents.
-               String body = String.join(//
-                               System.getProperty("line.separator"), //
-                               "<html>", //
-                               "<head>", //
-                               "<title>RIC Dashboard</title>", //
-                               "<style>", //
-                               "html, body { ", //
-                               "  font-family: Helvetica, Arial, sans-serif;", //
-                               "}", //
-                               "</style>", //
-                               "</head>", //
-                               "<body>", //
-                               "<h2>RIC Dashboard</h2>", //
-                               "<h4>Please log in.</h4>", //
-                               "<p>", //
-                               aHref, "Click here to authenticate at the ONAP Portal</a>", //
-                               "</p>", //
-                               "</body>", //
-                               "</html>");
-               return body;
-       }
+    /**
+     * Generates a page with text only, absolutely no references to any webapp
+     * resources, so this can be served to an unauthenticated user without
+     * triggering a new authentication attempt. The page has a link to the Portal
+     * URL from configuration, with a return URL that is the original request.
+     *
+     * @param appUrl
+     *        Original requested URL
+     * @return HTML
+     * @throws UnsupportedEncodingException
+     *         On error
+     */
+    private static String generateLoginRedirectPage(String appUrl) throws UnsupportedEncodingException {
+        String encodedAppUrl = URLEncoder.encode(appUrl, "UTF-8");
+        String portalBaseUrl = PortalApiProperties.getProperty(PortalApiConstants.ECOMP_REDIRECT_URL);
+        String redirectUrl = portalBaseUrl + "?" + PortalAuthenticationFilter.REDIRECT_URL_KEY + "=" + encodedAppUrl;
+        String aHref = "<a href=\"" + redirectUrl + "\">";
+        // If only Java had "here" documents.
+        String body = String.join(//
+            System.getProperty("line.separator"), //
+            "<html>", //
+            "<head>", //
+            "<title>RIC Dashboard</title>", //
+            "<style>", //
+            "html, body { ", //
+            "  font-family: Helvetica, Arial, sans-serif;", //
+            "}", //
+            "</style>", //
+            "</head>", //
+            "<body>", //
+            "<h2>RIC Dashboard</h2>", //
+            "<h4>Please log in.</h4>", //
+            "<p>", //
+            aHref, "Click here to authenticate at the ONAP Portal</a>", //
+            "</p>", //
+            "</body>", //
+            "</html>");
+        return body;
+    }
 
-       /**
-        * Searches the request for a cookie with the specified name.
-        *
-        * @param request
-        *                       HttpServletRequest
-        * @param cookieName
-        *                       Cookie name
-        * @return Cookie, or null if not found.
-        */
-       private Cookie getCookie(HttpServletRequest request, String cookieName) {
-               Cookie[] cookies = request.getCookies();
-               if (cookies != null)
-                       for (Cookie cookie : cookies)
-                               if (cookie.getName().equals(cookieName))
-                                       return cookie;
-               return null;
-       }
+    /**
+     * Searches the request for a cookie with the specified name.
+     *
+     * @param request
+     *        HttpServletRequest
+     * @param cookieName
+     *        Cookie name
+     * @return Cookie, or null if not found.
+     */
+    private Cookie getCookie(HttpServletRequest request, String cookieName) {
+        Cookie[] cookies = request.getCookies();
+        if (cookies != null)
+            for (Cookie cookie : cookies)
+                if (cookie.getName().equals(cookieName))
+                    return cookie;
+        return null;
+    }
 
-       /**
-        * Gets the ECOMP Portal service cookie value.
-        * 
-        * @param request
-        * @return Cookie value, or null if not found.
-        */
-       private String getPortalSessionId(HttpServletRequest request) {
-               Cookie ep = getCookie(request, PortalApiConstants.EP_SERVICE);
-               if (ep == null)
-                       return null;
-               return ep.getValue();
-       }
+    /**
+     * Gets the ECOMP Portal service cookie value.
+     *
+     * @param request
+     * @return Cookie value, or null if not found.
+     */
+    private String getPortalSessionId(HttpServletRequest request) {
+        Cookie ep = getCookie(request, PortalApiConstants.EP_SERVICE);
+        if (ep == null)
+            return null;
+        return ep.getValue();
+    }
 
 }
index 581ca25..a2fae9f 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -38,52 +38,52 @@ import org.springframework.context.ApplicationContext;
  * Implements the contract used by the Portal to transmit user details to this
  * on-boarded application. The requests are intercepted first by a servlet in
  * the EPSDK-FW library, which proxies the calls to these methods.
- * 
+ *
  * An instance of this class is created upon first request to the API. But this
  * class is found and instantiated via Class.forName(), so cannot use Spring
  * annotations.
  */
 public class PortalRestCentralServiceImpl implements IPortalRestCentralService {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       private final PortalAuthManager authManager;
-       private final DashboardUserManager userManager;
+    private final PortalAuthManager authManager;
+    private final DashboardUserManager userManager;
 
-       public PortalRestCentralServiceImpl() throws IOException, PortalAPIException {
-               final ApplicationContext context = SpringContextCache.getApplicationContext();
-               authManager = (PortalAuthManager) context.getBean(PortalAuthManager.class);
-               userManager = (DashboardUserManager) context.getBean(DashboardUserManager.class);
-       }
+    public PortalRestCentralServiceImpl() throws IOException, PortalAPIException {
+        final ApplicationContext context = SpringContextCache.getApplicationContext();
+        authManager = context.getBean(PortalAuthManager.class);
+        userManager = context.getBean(DashboardUserManager.class);
+    }
 
-       /*
-        * Answers the Portal API credentials.
-        */
-       @Override
-       public Map<String, String> getAppCredentials() throws PortalAPIException {
-               logger.debug("getAppCredentials");
-               return authManager.getAppCredentials();
-       }
+    /*
+     * Answers the Portal API credentials.
+     */
+    @Override
+    public Map<String, String> getAppCredentials() throws PortalAPIException {
+        logger.debug("getAppCredentials");
+        return authManager.getAppCredentials();
+    }
 
-       /*
-        * Extracts the user ID from a cookie in the header
-        */
-       @Override
-       public String getUserId(HttpServletRequest request) throws PortalAPIException {
-               logger.debug("getuserId");
-               return authManager.validateEcompSso(request);
-       }
+    /*
+     * Extracts the user ID from a cookie in the header
+     */
+    @Override
+    public String getUserId(HttpServletRequest request) throws PortalAPIException {
+        logger.debug("getuserId");
+        return authManager.validateEcompSso(request);
+    }
 
-       @Override
-       public void pushUser(EcompUser user) throws PortalAPIException {
-               logger.debug("pushUser: {}", user);
-               userManager.createUser(user);
-       }
+    @Override
+    public void pushUser(EcompUser user) throws PortalAPIException {
+        logger.debug("pushUser: {}", user);
+        userManager.createUser(user);
+    }
 
-       @Override
-       public void editUser(String loginId, EcompUser user) throws PortalAPIException {
-               logger.debug("editUser: {}", user);
-               userManager.updateUser(loginId, user);
-       }
+    @Override
+    public void editUser(String loginId, EcompUser user) throws PortalAPIException {
+        logger.debug("editUser: {}", user);
+        userManager.updateUser(loginId, user);
+    }
 
 }
index 279f1dd..f62ea5f 100644 (file)
@@ -24,9 +24,9 @@ import org.onap.portalsdk.core.onboarding.util.CipherUtil;
 
 public class PortalSdkDecryptorAes implements IPortalSdkDecryptor {
 
-       @SuppressWarnings("deprecation")
-       public String decrypt(String cipherText) throws CipherUtilException {
-               return CipherUtil.decrypt(cipherText);
-       }
+    @SuppressWarnings("deprecation")
+    public String decrypt(String cipherText) throws CipherUtilException {
+        return CipherUtil.decrypt(cipherText);
+    }
 
 }
index 0127267..1020527 100644 (file)
@@ -24,8 +24,8 @@ import org.onap.portalsdk.core.onboarding.util.CipherUtil;
 
 public class PortalSdkDecryptorPkc implements IPortalSdkDecryptor {
 
-       public String decrypt(String cipherText) throws CipherUtilException {
-               return CipherUtil.decryptPKC(cipherText);
-       }
+    public String decrypt(String cipherText) throws CipherUtilException {
+        return CipherUtil.decryptPKC(cipherText);
+    }
 
 }
index a97ed7b..d5f2cbf 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -35,48 +35,52 @@ import javax.net.ssl.X509TrustManager;
  * Disables and enables certificate and host-name checking in
  * HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
  * Has no effect on implementations such as Apache Http Client, Ok Http.
- * 
+ *
  * https://stackoverflow.com/questions/23504819/how-to-disable-ssl-certificate-checking-with-spring-resttemplate/58291331#58291331
  */
 public final class HttpsURLConnectionUtils {
 
-       private static final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+    private static final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
 
-       private static final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
-               public boolean verify(String hostname, SSLSession sslSession) {
-                       return true;
-               }
-       };
+    private static final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
+        @Override
+        public boolean verify(String hostname, SSLSession sslSession) {
+            return true;
+        }
+    };
 
-       private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
-               public java.security.cert.X509Certificate[] getAcceptedIssuers() {
-                       return null;
-               }
+    private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] {new X509TrustManager() {
+        @Override
+        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+            return null;
+        }
 
-               public void checkClientTrusted(X509Certificate[] certs, String authType) {
-               }
+        @Override
+        public void checkClientTrusted(X509Certificate[] certs, String authType) {
+        }
 
-               public void checkServerTrusted(X509Certificate[] certs, String authType) {
-               }
-       } };
+        @Override
+        public void checkServerTrusted(X509Certificate[] certs, String authType) {
+        }
+    }};
 
-       public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
-               HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
-               // Install the all-trusting trust manager
-               SSLContext sc = SSLContext.getInstance("SSL");
-               sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
-               HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-       }
+    public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
+        HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
+        // Install the all-trusting trust manager
+        SSLContext sc = SSLContext.getInstance("SSL");
+        sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
+        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+    }
 
-       public static void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
-               HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
-               // Return it to the initial state (discovered by reflection, now hardcoded)
-               SSLContext sc = SSLContext.getInstance("SSL");
-               sc.init(null, null, null);
-               HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
-       }
+    public static void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
+        HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
+        // Return it to the initial state (discovered by reflection, now hardcoded)
+        SSLContext sc = SSLContext.getInstance("SSL");
+        sc.init(null, null, null);
+        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+    }
 
-       private HttpsURLConnectionUtils() {
-               throw new UnsupportedOperationException("Do not instantiate libraries.");
-       }
+    private HttpsURLConnectionUtils() {
+        throw new UnsupportedOperationException("Do not instantiate libraries.");
+    }
 }
index a6c0a1e..e19890b 100644 (file)
@@ -22,6 +22,7 @@ package org.oransc.ric.portal.dashboard;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
 import java.lang.invoke.MethodHandles;
+
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -29,7 +30,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 /**
@@ -49,23 +49,23 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
 public class DashboardTestServer {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       /*
-        * Keeps the test server alive forever. Use a guard so this test is never run by
-        * Jenkins.
-        */
-       @EnabledIfSystemProperty(named = "org.oransc.ric.portal.dashboard", matches = "mock")
-       @Test
-       public void keepServerAlive() {
-               logger.warn("Keeping server alive!");
-               try {
-                       synchronized (this) {
-                               this.wait();
-                       }
-               } catch (Exception ex) {
-                       logger.warn(ex.toString());
-               }
-               assertEquals(1, 2);
-       }
+    /*
+     * Keeps the test server alive forever. Use a guard so this test is never run by
+     * Jenkins.
+     */
+    @EnabledIfSystemProperty(named = "org.oransc.ric.portal.dashboard", matches = "mock")
+    @Test
+    public void keepServerAlive() {
+        logger.warn("Keeping server alive!");
+        try {
+            synchronized (this) {
+                this.wait();
+            }
+        } catch (Exception ex) {
+            logger.warn(ex.toString());
+        }
+        assertEquals(1, 2);
+    }
 }
index 44d0b5c..e695b68 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.oransc.ric.portal.dashboard.config;
 
+import com.google.gson.GsonBuilder;
+
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -42,6 +44,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.boot.test.context.TestConfiguration;
 import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.client.RestClientException;
 
 /**
@@ -50,142 +54,148 @@ import org.springframework.web.client.RestClientException;
 @TestConfiguration
 public class PolicyControllerMockConfiguration {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       @Bean
-       public PolicyAgentApi policyAgentApi() {
-               MockPolicyAgentApi apiClient = new MockPolicyAgentApi();
-               return apiClient;
-       }
-
-       class MockPolicyAgentApi implements PolicyAgentApi {
-               private final Database database = new Database();
-
-               @Override
-               public String getPolicyInstance(String id) throws RestClientException {
-                       return database.getInstance(id);
-               }
-
-               @Override
-               public void putPolicy(String policyTypeIdString, String policyInstanceId, String json, String ric)
-                               throws RestClientException {
-                       database.putInstance(policyTypeIdString, policyInstanceId, json, ric);
-               }
-
-               @Override
-               public void deletePolicy(String policyInstanceId) throws RestClientException {
-                       database.deleteInstance(policyInstanceId);
-               }
-
-               @Override
-               public PolicyTypes getAllPolicyTypes() throws RestClientException {
-                       PolicyTypes result = new PolicyTypes();
-                       result.addAll(database.getTypes());
-                       return result;
-               }
-
-               @Override
-               public PolicyInstances getPolicyInstancesForType(String type) {
-                       PolicyInstances result = new PolicyInstances();
-                       List<PolicyInfo> inst = database.getInstances(Optional.of(type));
-                       result.addAll(inst);
-                       return result;
-               }
-
-               @Override
-               public Collection<String> getRicsSupportingType(String typeName) {
-                       Vector<String> res = new Vector<>();
-                       res.add("ric_1");
-                       res.add("ric_2");
-                       res.add("ric_3");
-                       return res;
-               }
-       }
-
-       class Database {
-
-               Database() {
-                       String schema = getStringFromFile("anr-policy-schema.json");
-                       PolicyType policy = new PolicyType("ANR", schema);
-                       types.put("ANR", policy);
-
-                       schema = getStringFromFile("demo-policy-schema-1.json");
-                       policy = new PolicyType("type2", schema);
-                       types.put("type2", policy);
-
-                       schema = getStringFromFile("demo-policy-schema-2.json");
-                       policy = new PolicyType("type3", schema);
-                       types.put("type3", policy);
-
-                       schema = getStringFromFile("demo-policy-schema-3.json");
-                       policy = new PolicyType("type4", schema);
-                       types.put("type4", policy);
-                       try {
-                               putInstance("ANR", "ANR-1", getStringFromFile("anr-policy-instance.json"), "ric_1");
-                       } catch (Exception e) {
-                               // Nothing
-                       }
-               }
-
-               private String getStringFromFile(String path) {
-                       try {
-                               InputStream inputStream = MethodHandles.lookup().lookupClass().getClassLoader()
-                                               .getResourceAsStream(path);
-                               return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n"));
-                       } catch (Exception e) {
-                               logger.error("Cannot read file :" + path, e);
-                               return "";
-                       }
-               }
-
-               String normalize(String str) {
-                       return str.replace('\n', ' ');
-               }
-
-               private String getTimeStampUTC() {
-                       return java.time.Instant.now().toString();
-               }
-
-               void putInstance(String typeId, String instanceId, String instanceData, String ric) {
-                       PolicyInfo i = ImmutablePolicyInfo.builder().json(instanceData).lastModified(getTimeStampUTC())
-                                       .id(instanceId).ric(ric).service("service").type(typeId).build();
-                       instances.put(instanceId, i);
-               }
-
-               public void deleteInstance(String instanceId) {
-                       instances.remove(instanceId);
-               }
-
-               String getInstance(String id) throws RestClientException {
-                       PolicyInfo i = instances.get(id);
-                       if (i == null) {
-                               throw new RestClientException("Type not found: " + id);
-                       }
-                       return i.json();
-               }
-
-               public Collection<PolicyType> getTypes() {
-                       return types.values();
-               }
-
-               public List<PolicyInfo> getInstances(Optional<String> typeId) {
-                       ArrayList<PolicyInfo> result = new ArrayList<>();
-                       for (PolicyInfo i : instances.values()) {
-                               if (typeId.isPresent()) {
-                                       if (i.type().equals(typeId.get())) {
-                                               result.add(i);
-                                       }
-
-                               } else {
-                                       result.add(i);
-                               }
-                       }
-                       return result;
-               }
-
-               private Map<String, PolicyType> types = new HashMap<>();
-               private Map<String, PolicyInfo> instances = new HashMap<>();
-
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+
+    private static com.google.gson.Gson gson = new GsonBuilder() //
+        .serializeNulls() //
+        .create(); //
+
+    @Bean
+    public PolicyAgentApi policyAgentApi() {
+        MockPolicyAgentApi apiClient = new MockPolicyAgentApi();
+        return apiClient;
+    }
+
+    class MockPolicyAgentApi implements PolicyAgentApi {
+        private final Database database = new Database();
+
+        @Override
+        public ResponseEntity<String> getPolicyInstance(String id) {
+            return new ResponseEntity<>(database.getInstance(id), HttpStatus.OK);
+        }
+
+        @Override
+        public ResponseEntity<String> putPolicy(String policyTypeIdString, String policyInstanceId, String json,
+            String ric) {
+            database.putInstance(policyTypeIdString, policyInstanceId, json, ric);
+            return new ResponseEntity<>("Policy was put successfully", HttpStatus.OK);
+        }
+
+        @Override
+        public ResponseEntity<String> deletePolicy(String policyInstanceId) {
+            database.deleteInstance(policyInstanceId);
+            return new ResponseEntity<>("Policy was deleted successfully", HttpStatus.NO_CONTENT);
+        }
+
+        @Override
+        public ResponseEntity<String> getAllPolicyTypes() {
+            PolicyTypes result = new PolicyTypes();
+            result.addAll(database.getTypes());
+            return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
+        }
+
+        @Override
+        public ResponseEntity<String> getPolicyInstancesForType(String type) {
+            PolicyInstances result = new PolicyInstances();
+            List<PolicyInfo> inst = database.getInstances(Optional.of(type));
+            result.addAll(inst);
+            return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
+        }
+
+        @Override
+        public ResponseEntity<String> getRicsSupportingType(String typeName) {
+            Vector<String> res = new Vector<>();
+            res.add("ric_1");
+            res.add("ric_2");
+            res.add("ric_3");
+            return new ResponseEntity<>(gson.toJson(res), HttpStatus.OK);
+        }
+    }
+
+    class Database {
+
+        Database() {
+            String schema = getStringFromFile("anr-policy-schema.json");
+            PolicyType policy = new PolicyType("ANR", schema);
+            types.put("ANR", policy);
+
+            schema = getStringFromFile("demo-policy-schema-1.json");
+            policy = new PolicyType("type2", schema);
+            types.put("type2", policy);
+
+            schema = getStringFromFile("demo-policy-schema-2.json");
+            policy = new PolicyType("type3", schema);
+            types.put("type3", policy);
+
+            schema = getStringFromFile("demo-policy-schema-3.json");
+            policy = new PolicyType("type4", schema);
+            types.put("type4", policy);
+            try {
+                putInstance("ANR", "ANR-1", getStringFromFile("anr-policy-instance.json"), "ric_1");
+            } catch (Exception e) {
+                // Nothing
+            }
+        }
+
+        private String getStringFromFile(String path) {
+            try {
+                InputStream inputStream =
+                    MethodHandles.lookup().lookupClass().getClassLoader().getResourceAsStream(path);
+                return new BufferedReader(new InputStreamReader(inputStream)).lines().collect(Collectors.joining("\n"));
+            } catch (Exception e) {
+                logger.error("Cannot read file :" + path, e);
+                return "";
+            }
+        }
+
+        String normalize(String str) {
+            return str.replace('\n', ' ');
+        }
+
+        private String getTimeStampUTC() {
+            return java.time.Instant.now().toString();
+        }
+
+        void putInstance(String typeId, String instanceId, String instanceData, String ric) {
+            PolicyInfo i = ImmutablePolicyInfo.builder().json(instanceData).lastModified(getTimeStampUTC())
+                .id(instanceId).ric(ric).service("service").type(typeId).build();
+            instances.put(instanceId, i);
+        }
+
+        public void deleteInstance(String instanceId) {
+            instances.remove(instanceId);
+        }
+
+        String getInstance(String id) throws RestClientException {
+            PolicyInfo i = instances.get(id);
+            if (i == null) {
+                throw new RestClientException("Type not found: " + id);
+            }
+            return i.json();
+        }
+
+        public Collection<PolicyType> getTypes() {
+            return types.values();
+        }
+
+        public List<PolicyInfo> getInstances(Optional<String> typeId) {
+            ArrayList<PolicyInfo> result = new ArrayList<>();
+            for (PolicyInfo i : instances.values()) {
+                if (typeId.isPresent()) {
+                    if (i.type().equals(typeId.get())) {
+                        result.add(i);
+                    }
+
+                } else {
+                    result.add(i);
+                }
+            }
+            return result;
+        }
+
+        private Map<String, PolicyType> types = new HashMap<>();
+        private Map<String, PolicyInfo> instances = new HashMap<>();
+
+    }
 
 }
index a3d05be..01265d9 100644 (file)
@@ -43,41 +43,41 @@ import org.springframework.context.annotation.Profile;
 @Profile("test")
 public class PortalApIMockConfiguration {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    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";
+    // 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 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).validateEcompSso(any(HttpServletRequest.class));
-               doAnswer(inv -> {
-                       logger.debug("getAppCredentials");
-                       return credentialsMap;
-               }).when(mockManager).getAppCredentials();
-               return mockManager;
-       }
+    @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).validateEcompSso(any(HttpServletRequest.class));
+        doAnswer(inv -> {
+            logger.debug("getAppCredentials");
+            return credentialsMap;
+        }).when(mockManager).getAppCredentials();
+        return mockManager;
+    }
 
 }
index 80cde66..3e75606 100644 (file)
@@ -42,43 +42,43 @@ import org.springframework.security.crypto.password.PasswordEncoder;
 @Profile("test")
 public class WebSecurityMockConfiguration extends WebSecurityConfigurerAdapter {
 
-       public static final String TEST_CRED_ADMIN = "admin";
-       public static final String TEST_CRED_STANDARD = "standard";
+    public static final String TEST_CRED_ADMIN = "admin";
+    public static final String TEST_CRED_STANDARD = "standard";
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       public WebSecurityMockConfiguration(@Value("${userfile}") final String userFilePath) {
-               logger.debug("ctor: user file path {}", userFilePath);
-       }
+    public WebSecurityMockConfiguration(@Value("${userfile}") final String userFilePath) {
+        logger.debug("ctor: user file path {}", userFilePath);
+    }
 
-       @Override
-       protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-               PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
-               auth.inMemoryAuthentication() //
-                               .passwordEncoder(encoder) //
-                               // The admin user has the admin AND standard roles
-                               .withUser(TEST_CRED_ADMIN) //
-                               .password(encoder.encode(TEST_CRED_ADMIN))
-                               .roles(DashboardConstants.ROLE_NAME_ADMIN, DashboardConstants.ROLE_NAME_STANDARD)//
-                               .and()//
-                               // The standard user has only the standard role
-                               .withUser(TEST_CRED_STANDARD) //
-                               .password(encoder.encode(TEST_CRED_STANDARD)) //
-                               .roles(DashboardConstants.ROLE_NAME_STANDARD);
-       }
+    @Override
+    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
+        PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
+        auth.inMemoryAuthentication() //
+            .passwordEncoder(encoder) //
+            // The admin user has the admin AND standard roles
+            .withUser(TEST_CRED_ADMIN) //
+            .password(encoder.encode(TEST_CRED_ADMIN))
+            .roles(DashboardConstants.ROLE_NAME_ADMIN, DashboardConstants.ROLE_NAME_STANDARD)//
+            .and()//
+            // The standard user has only the standard role
+            .withUser(TEST_CRED_STANDARD) //
+            .password(encoder.encode(TEST_CRED_STANDARD)) //
+            .roles(DashboardConstants.ROLE_NAME_STANDARD);
+    }
 
-       @Override
-       protected void configure(HttpSecurity http) throws Exception {
-               http.authorizeRequests().anyRequest().authenticated()//
-                               .and().httpBasic() //
-                               .and().csrf().disable();
-       }
+    @Override
+    protected void configure(HttpSecurity http) throws Exception {
+        http.authorizeRequests().anyRequest().authenticated()//
+            .and().httpBasic() //
+            .and().csrf().disable();
+    }
 
-       @Override
-       public void configure(WebSecurity web) throws Exception {
-               // This disables Spring security, but not the app's filter.
-               web.ignoring().antMatchers(WebSecurityConfiguration.OPEN_PATHS);
-               web.ignoring().antMatchers("/", "/csrf"); // allow swagger-ui to load
-       }
+    @Override
+    public void configure(WebSecurity web) throws Exception {
+        // This disables Spring security, but not the app's filter.
+        web.ignoring().antMatchers(WebSecurityConfiguration.OPEN_PATHS);
+        web.ignoring().antMatchers("/", "/csrf"); // allow swagger-ui to load
+    }
 
 }
index d4163f0..09d3a86 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -44,69 +44,69 @@ import org.springframework.web.util.UriComponentsBuilder;
 @ActiveProfiles("test")
 public class AbstractControllerTest {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       // Created by Spring black magic
-       // https://spring.io/guides/gs/testing-web/
-       @LocalServerPort
-       private int localServerPort;
+    // Created by Spring black magic
+    // https://spring.io/guides/gs/testing-web/
+    @LocalServerPort
+    private int localServerPort;
 
-       @Autowired
-       protected TestRestTemplate restTemplate;
+    @Autowired
+    protected TestRestTemplate restTemplate;
 
-       /**
-        * Flexible URI builder.
-        * 
-        * @param queryParams
-        *                        Map of string-string query parameters
-        * @param path
-        *                        Array of path components. If a component has an
-        *                        embedded slash, the string is split and each
-        *                        subcomponent is added individually.
-        * @return URI
-        */
-       protected URI buildUri(final Map<String, String> queryParams, final String... path) {
-               UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:" + localServerPort + "/");
-               for (int p = 0; p < path.length; ++p) {
-                       if (path[p] == null || path[p].isEmpty()) {
-                               throw new IllegalArgumentException("Unexpected null or empty at path index " + Integer.toString(p));
-                       } else if (path[p].contains("/")) {
-                               String[] subpaths = path[p].split("/");
-                               for (String s : subpaths)
-                                       if (!s.isEmpty())
-                                               builder.pathSegment(s);
-                       } else {
-                               builder.pathSegment(path[p]);
-                       }
-               }
-               if (queryParams != null && queryParams.size() > 0) {
-                       for (Map.Entry<String, String> entry : queryParams.entrySet()) {
-                               if (entry.getKey() == null || entry.getValue() == null)
-                                       throw new IllegalArgumentException("Unexpected null key or value");
-                               else
-                                       builder.queryParam(entry.getKey(), entry.getValue());
-                       }
-               }
-               return builder.build().encode().toUri();
-       }
+    /**
+     * Flexible URI builder.
+     *
+     * @param queryParams
+     *        Map of string-string query parameters
+     * @param path
+     *        Array of path components. If a component has an
+     *        embedded slash, the string is split and each
+     *        subcomponent is added individually.
+     * @return URI
+     */
+    protected URI buildUri(final Map<String, String> queryParams, final String... path) {
+        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://localhost:" + localServerPort + "/");
+        for (int p = 0; p < path.length; ++p) {
+            if (path[p] == null || path[p].isEmpty()) {
+                throw new IllegalArgumentException("Unexpected null or empty at path index " + Integer.toString(p));
+            } else if (path[p].contains("/")) {
+                String[] subpaths = path[p].split("/");
+                for (String s : subpaths)
+                    if (!s.isEmpty())
+                        builder.pathSegment(s);
+            } else {
+                builder.pathSegment(path[p]);
+            }
+        }
+        if (queryParams != null && queryParams.size() > 0) {
+            for (Map.Entry<String, String> entry : queryParams.entrySet()) {
+                if (entry.getKey() == null || entry.getValue() == null)
+                    throw new IllegalArgumentException("Unexpected null key or value");
+                else
+                    builder.queryParam(entry.getKey(), entry.getValue());
+            }
+        }
+        return builder.build().encode().toUri();
+    }
 
-       // Because I put the annotations on this parent class,
-       // must define at least one test here.
-       @Test
-       public void contextLoads() {
-               // Silence Sonar warning about missing assertion.
-               Assertions.assertTrue(logger.isWarnEnabled());
-               logger.info("Context loads on mock profile");
-       }
+    // Because I put the annotations on this parent class,
+    // must define at least one test here.
+    @Test
+    public void contextLoads() {
+        // Silence Sonar warning about missing assertion.
+        Assertions.assertTrue(logger.isWarnEnabled());
+        logger.info("Context loads on mock profile");
+    }
 
-       public TestRestTemplate testRestTemplateAdminRole() {
-               return restTemplate.withBasicAuth(WebSecurityMockConfiguration.TEST_CRED_ADMIN,
-                               WebSecurityMockConfiguration.TEST_CRED_ADMIN);
-       }
+    public TestRestTemplate testRestTemplateAdminRole() {
+        return restTemplate.withBasicAuth(WebSecurityMockConfiguration.TEST_CRED_ADMIN,
+            WebSecurityMockConfiguration.TEST_CRED_ADMIN);
+    }
 
-       public TestRestTemplate testRestTemplateStandardRole() {
-               return restTemplate.withBasicAuth(WebSecurityMockConfiguration.TEST_CRED_STANDARD,
-                               WebSecurityMockConfiguration.TEST_CRED_STANDARD);
-       }
+    public TestRestTemplate testRestTemplateStandardRole() {
+        return restTemplate.withBasicAuth(WebSecurityMockConfiguration.TEST_CRED_STANDARD,
+            WebSecurityMockConfiguration.TEST_CRED_STANDARD);
+    }
 
 }
index 48c5931..643f15e 100644 (file)
@@ -36,13 +36,13 @@ import org.springframework.test.context.junit.jupiter.SpringExtension;
 @SpringBootTest
 public class DefaultContextTest {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       @Test
-       public void contextLoads() {
-               // Silence Sonar warning about missing assertion.
-               Assertions.assertTrue(logger.isWarnEnabled());
-               logger.info("Context loads on default profile");
-       }
+    @Test
+    public void contextLoads() {
+        // Silence Sonar warning about missing assertion.
+        Assertions.assertTrue(logger.isWarnEnabled());
+        logger.info("Context loads on default profile");
+    }
 
 }
index dc80968..b9f1635 100644 (file)
@@ -7,9 +7,9 @@
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,97 +21,90 @@ package org.oransc.ric.portal.dashboard.controller;
 
 import java.lang.invoke.MethodHandles;
 import java.net.URI;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 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.config.PortalApIMockConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.http.HttpEntity;
-import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
 import org.springframework.http.ResponseEntity;
 
 public class PortalRestCentralServiceTest extends AbstractControllerTest {
 
-       private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
-
-       @Test
-       public void getAnalyticsTest() {
-               // paths are hardcoded here exactly like the EPSDK-FW library :(
-               URI uri = buildUri(null, PortalApiConstants.API_PREFIX, "/analytics");
-               logger.info("Invoking {}", uri);
-               ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
-               // No Portal is available so this always fails
-               Assertions.assertTrue(response.getStatusCode().is4xxClientError());
-       }
-
-       @Test
-       public void getErrorPageTest() {
-               // Send unauthorized request
-               URI uri = buildUri(null, "/favicon.ico");
-               logger.info("Invoking {}", uri);
-               ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
-               Assertions.assertTrue(response.getStatusCode().is4xxClientError());
-               Assertions.assertTrue(response.getBody().contains("Static error page"));
-       }
-
-       private HttpEntity<Object> getEntityWithHeaders(Object body) {
-               HttpHeaders headers = new HttpHeaders();
-               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;
-       }
+    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
-       private EcompUser createEcompUser(String loginId) {
-               EcompUser user = new EcompUser();
-               user.setLoginId(loginId);
-               EcompRole role = new EcompRole();
-               role.setRoleFunctions(Collections.EMPTY_SET);
-               role.setId(1L);
-               role.setName(DashboardConstants.ROLE_NAME_ADMIN);
-               Set<EcompRole> roles = new HashSet<>();
-               roles.add(role);
-               user.setRoles(roles);
-               return user;
-       }
+    @Test
+    public void getAnalyticsTest() {
+        // paths are hardcoded here exactly like the EPSDK-FW library :(
+        URI uri = buildUri(null, PortalApiConstants.API_PREFIX, "/analytics");
+        logger.info("Invoking {}", uri);
+        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
+        // No Portal is available so this always fails
+        Assertions.assertTrue(response.getStatusCode().is4xxClientError());
+    }
 
-/*     @Test
-       public void createUserTest() {
-               final String loginId = "login1";
-               URI create = buildUri(null, PortalApiConstants.API_PREFIX, "user");
-               logger.info("Invoking {}", create);
-               HttpEntity<Object> requestEntity = getEntityWithHeaders(createEcompUser(loginId));
-               ResponseEntity<String> response = restTemplate.exchange(create, HttpMethod.POST, requestEntity, String.class);
-               Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
-       }
+    @Test
+    public void getErrorPageTest() {
+        // Send unauthorized request
+        URI uri = buildUri(null, "/favicon.ico");
+        logger.info("Invoking {}", uri);
+        ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.GET, null, String.class);
+        Assertions.assertTrue(response.getStatusCode().is4xxClientError());
+        Assertions.assertTrue(response.getBody().contains("Static error page"));
+    }
 
-       @Test
-       public void updateUserTest() {
-               final String loginId = "login2";
-               URI create = buildUri(null, PortalApiConstants.API_PREFIX, "user");
-               EcompUser user = createEcompUser(loginId);
-               logger.info("Invoking {}", create);
-               HttpEntity<Object> requestEntity = getEntityWithHeaders(user);
-               // Create
-               ResponseEntity<String> response = restTemplate.exchange(create, HttpMethod.POST, requestEntity, String.class);
-               Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
-               URI update = buildUri(null, PortalApiConstants.API_PREFIX, "user", loginId);
-               user.setEmail("user@company.org");
-               requestEntity = getEntityWithHeaders(user);
-               response = restTemplate.exchange(update, HttpMethod.POST, requestEntity, String.class);
-               Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
-       }
-*/
+    /*
+     * private HttpEntity<Object> getEntityWithHeaders(Object body) {
+     * HttpHeaders headers = new HttpHeaders();
+     * 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;
+     * }
+     *
+     * private EcompUser createEcompUser(String loginId) {
+     * EcompUser user = new EcompUser();
+     * user.setLoginId(loginId);
+     * EcompRole role = new EcompRole();
+     * role.setRoleFunctions(Collections.EMPTY_SET);
+     * role.setId(1L);
+     * role.setName(DashboardConstants.ROLE_NAME_ADMIN);
+     * Set<EcompRole> roles = new HashSet<>();
+     * roles.add(role);
+     * user.setRoles(roles);
+     * return user;
+     * }
+     *
+     * @Test
+     *
+     * @Test
+     * public void createUserTest() {
+     * final String loginId = "login1";
+     * URI create = buildUri(null, PortalApiConstants.API_PREFIX, "user");
+     * logger.info("Invoking {}", create);
+     * HttpEntity<Object> requestEntity = getEntityWithHeaders(createEcompUser(loginId));
+     * ResponseEntity<String> response = restTemplate.exchange(create, HttpMethod.POST, requestEntity, String.class);
+     * Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
+     * }
+     *
+     * @Test
+     * public void updateUserTest() {
+     * final String loginId = "login2";
+     * URI create = buildUri(null, PortalApiConstants.API_PREFIX, "user");
+     * EcompUser user = createEcompUser(loginId);
+     * logger.info("Invoking {}", create);
+     * HttpEntity<Object> requestEntity = getEntityWithHeaders(user);
+     * // Create
+     * ResponseEntity<String> response = restTemplate.exchange(create, HttpMethod.POST, requestEntity, String.class);
+     * Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
+     * URI update = buildUri(null, PortalApiConstants.API_PREFIX, "user", loginId);
+     * user.setEmail("user@company.org");
+     * requestEntity = getEntityWithHeaders(user);
+     * response = restTemplate.exchange(update, HttpMethod.POST, requestEntity, String.class);
+     * Assertions.assertTrue(response.getStatusCode().is2xxSuccessful());
+     * }
+     */
 
 }
index bc6d7cd..8d244ee 100644 (file)
@@ -22,6 +22,7 @@ package org.oransc.policyagent.clients;
 
 import java.util.Collection;
 
+import org.oransc.policyagent.repository.Policy;
 import reactor.core.publisher.Mono;
 
 public interface A1Client {
@@ -32,7 +33,7 @@ public interface A1Client {
 
     public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId);
 
-    public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString);
+    public Mono<String> putPolicy(Policy policy);
 
     public Mono<String> deletePolicy(String nearRtRicUrl, String policyId);
 
index b3773b8..e576638 100644 (file)
@@ -28,6 +28,7 @@ import java.util.List;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.oransc.policyagent.repository.Policy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import reactor.core.publisher.Mono;
@@ -39,7 +40,7 @@ public class A1ClientImpl implements A1Client {
         return nearRtRicUrl + "/A1-P/v1";
     }
 
-    public AsyncRestClient createClient(final String nearRtRicUrl) {
+    protected AsyncRestClient createClient(final String nearRtRicUrl) {
         return new AsyncRestClient(getBaseUrl(nearRtRicUrl));
     }
 
@@ -68,11 +69,15 @@ public class A1ClientImpl implements A1Client {
     }
 
     @Override
-    public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
-        logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", nearRtRicUrl, policyId,
-            policyString);
-        AsyncRestClient client = createClient(nearRtRicUrl);
-        Mono<String> response = client.put("/policies/" + policyId, policyString);
+    public Mono<String> putPolicy(Policy policy) {
+        logger.debug("putPolicy nearRtRicUrl = {}, policyId = {}, policyString = {}", //
+            policy.ric().getConfig().baseUrl(), policy.id(), policy.json());
+        AsyncRestClient client = createClient(policy.ric().getConfig().baseUrl());
+        // TODO update when simulator is updated to include policy type
+        // Mono<String> response = client.put("/policies/" + policy.id() + "?policyTypeId=" + policy.type().name(),
+        // policy.json());
+        Mono<String> response = client.put("/policies/" + policy.id(), policy.json());
+
         return response.flatMap(this::createMono);
     }
 
index 00e5223..7e52284 100644 (file)
@@ -33,6 +33,9 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.time.Duration;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.ServiceLoader;
@@ -68,25 +71,30 @@ public class ApplicationConfig {
     Properties systemEnvironment;
 
     private Disposable refreshConfigTask = null;
+    private Collection<Observer> observers = new Vector<>();
+
+    private Map<String, RicConfig> ricConfigs = new HashMap<>();
 
     @NotEmpty
     private String filepath;
 
-    private Vector<RicConfig> ricConfigs;
-
     @Autowired
     public ApplicationConfig() {
     }
 
+    protected String getLocalConfigurationFilePath() {
+        return this.filepath;
+    }
+
     public synchronized void setFilepath(String filepath) {
         this.filepath = filepath;
     }
 
-    public Vector<RicConfig> getRicConfigs() {
-        return this.ricConfigs;
+    public synchronized Collection<RicConfig> getRicConfigs() {
+        return this.ricConfigs.values();
     }
 
-    public Optional<RicConfig> lookupRicConfigForManagedElement(String managedElementId) {
+    public synchronized Optional<RicConfig> lookupRicConfigForManagedElement(String managedElementId) {
         for (RicConfig ricConfig : getRicConfigs()) {
             if (ricConfig.managedElementIds().contains(managedElementId)) {
                 return Optional.of(ricConfig);
@@ -106,7 +114,7 @@ public class ApplicationConfig {
 
     public void initialize() {
         stop();
-        loadConfigurationFromFile(this.filepath);
+        loadConfigurationFromFile();
 
         refreshConfigTask = createRefreshTask() //
             .subscribe(notUsed -> logger.info("Refreshed configuration data"),
@@ -114,6 +122,18 @@ public class ApplicationConfig {
                 () -> logger.error("Configuration refresh terminated"));
     }
 
+    public static enum RicConfigUpdate {
+        ADDED, CHANGED, REMOVED
+    }
+
+    public interface Observer {
+        void onRicConfigUpdate(RicConfig ric, RicConfigUpdate event);
+    }
+
+    public void addObserver(Observer o) {
+        this.observers.add(o);
+    }
+
     Mono<EnvProperties> getEnvironment(Properties systemEnvironment) {
         return EnvironmentProcessor.readEnvironmentVariables(systemEnvironment);
     }
@@ -154,8 +174,48 @@ public class ApplicationConfig {
         return this;
     }
 
-    private synchronized void setConfiguration(@NotNull Vector<RicConfig> ricConfigs) {
-        this.ricConfigs = ricConfigs;
+    private class Notification {
+        final RicConfig ric;
+        final RicConfigUpdate event;
+
+        Notification(RicConfig ric, RicConfigUpdate event) {
+            this.ric = ric;
+            this.event = event;
+        }
+    }
+
+    private void setConfiguration(@NotNull Collection<RicConfig> ricConfigs) {
+        Collection<Notification> notifications = new Vector<>();
+        synchronized (this) {
+            Map<String, RicConfig> newRicConfigs = new HashMap<>();
+            for (RicConfig newConfig : ricConfigs) {
+                RicConfig oldConfig = this.ricConfigs.get(newConfig.name());
+                if (oldConfig == null) {
+                    newRicConfigs.put(newConfig.name(), newConfig);
+                    notifications.add(new Notification(newConfig, RicConfigUpdate.ADDED));
+                    this.ricConfigs.remove(newConfig.name());
+                } else if (!newConfig.equals(newConfig)) {
+                    notifications.add(new Notification(newConfig, RicConfigUpdate.CHANGED));
+                    newRicConfigs.put(newConfig.name(), newConfig);
+                    this.ricConfigs.remove(newConfig.name());
+                } else {
+                    newRicConfigs.put(oldConfig.name(), oldConfig);
+                }
+            }
+            for (RicConfig deletedConfig : this.ricConfigs.values()) {
+                notifications.add(new Notification(deletedConfig, RicConfigUpdate.REMOVED));
+            }
+            this.ricConfigs = newRicConfigs;
+        }
+        notifyObservers(notifications);
+    }
+
+    private void notifyObservers(Collection<Notification> notifications) {
+        for (Observer observer : this.observers) {
+            for (Notification notif : notifications) {
+                observer.onRicConfigUpdate(notif.ric, notif.event);
+            }
+        }
     }
 
     public void stop() {
@@ -168,7 +228,12 @@ public class ApplicationConfig {
     /**
      * Reads the configuration from file.
      */
-    protected void loadConfigurationFromFile(String filepath) {
+    public void loadConfigurationFromFile() {
+        String filepath = getLocalConfigurationFilePath();
+        if (filepath == null) {
+            logger.debug("No localconfiguration file used");
+            return;
+        }
         GsonBuilder gsonBuilder = new GsonBuilder();
         ServiceLoader.load(TypeAdapterFactory.class).forEach(gsonBuilder::registerTypeAdapterFactory);
 
@@ -180,7 +245,7 @@ public class ApplicationConfig {
             }
             ApplicationConfigParser appParser = new ApplicationConfigParser();
             appParser.parse(rootObject);
-            this.ricConfigs = appParser.getRicConfigs();
+            setConfiguration(appParser.getRicConfigs());
             logger.info("Local configuration file loaded: {}", filepath);
         } catch (JsonSyntaxException | ServiceException | IOException e) {
             logger.trace("Local configuration file not loaded: {}", filepath, e);
diff --git a/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java b/policy-agent/src/main/java/org/oransc/policyagent/configuration/ApplicationConfigLoader.java
deleted file mode 100644 (file)
index e1eb17a..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * ========================LICENSE_START=================================
- * O-RAN-SC
- * %%
- * Copyright (C) 2019 Nordix Foundation
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR 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.policyagent.configuration;
-
-import io.swagger.annotations.ApiOperation;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ScheduledFuture;
-
-import javax.annotation.PostConstruct;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.scheduling.TaskScheduler;
-import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.stereotype.Component;
-import reactor.core.publisher.Mono;
-
-@Component
-@EnableScheduling
-class ApplicationConfigLoader {
-
-    private static final Logger logger = LoggerFactory.getLogger(ApplicationConfigLoader.class);
-    private static List<ScheduledFuture<?>> scheduledFutureList = new ArrayList<>();
-    private static final Duration CONFIGURATION_REFRESH_INTERVAL = Duration.ofSeconds(15);
-
-    private final TaskScheduler taskScheduler;
-    private final ApplicationConfig configuration;
-
-    @Autowired
-    public ApplicationConfigLoader(TaskScheduler taskScheduler, ApplicationConfig configuration) {
-        this.taskScheduler = taskScheduler;
-        this.configuration = configuration;
-    }
-
-    /**
-     * Function which have to stop tasks execution.
-     *
-     * @return response entity about status of cancellation operation
-     */
-    @ApiOperation(value = "Get response on stopping task execution")
-    public synchronized Mono<ResponseEntity<String>> getResponseFromCancellationOfTasks() {
-        scheduledFutureList.forEach(x -> x.cancel(false));
-        scheduledFutureList.clear();
-        logger.info("Stopped");
-        return Mono.just(new ResponseEntity<>("Service has already been stopped!", HttpStatus.CREATED));
-    }
-
-    @PostConstruct
-    @ApiOperation(value = "Start task if possible")
-    public synchronized boolean start() {
-        logger.info("Start scheduling Datafile workflow");
-        configuration.initialize();
-
-        if (scheduledFutureList.isEmpty()) {
-            scheduledFutureList
-                .add(taskScheduler.scheduleWithFixedDelay(this::refreshConfiguration, CONFIGURATION_REFRESH_INTERVAL));
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    private void refreshConfiguration() {
-        // TBD
-
-    }
-
-}
index 6d849b1..246fdd4 100644 (file)
@@ -77,15 +77,17 @@ public class PolicyController {
     @ApiOperation(value = "Returns policy type schema definitions")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy Types found")})
     public ResponseEntity<String> getPolicySchemas(@RequestParam(name = "ric", required = false) String ricName) {
-        if (ricName == null) {
-            Collection<PolicyType> types = this.policyTypes.getAll();
-            return new ResponseEntity<String>(toPolicyTypeSchemasJson(types), HttpStatus.OK);
-        } else {
-            try {
-                Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
+        synchronized (this.policyTypes) {
+            if (ricName == null) {
+                Collection<PolicyType> types = this.policyTypes.getAll();
                 return new ResponseEntity<String>(toPolicyTypeSchemasJson(types), HttpStatus.OK);
-            } catch (ServiceException e) {
-                return new ResponseEntity<String>(e.toString(), HttpStatus.NOT_FOUND);
+            } else {
+                try {
+                    Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
+                    return new ResponseEntity<String>(toPolicyTypeSchemasJson(types), HttpStatus.OK);
+                } catch (ServiceException e) {
+                    return new ResponseEntity<String>(e.toString(), HttpStatus.NOT_FOUND);
+                }
             }
         }
     }
@@ -106,15 +108,17 @@ public class PolicyController {
     @ApiOperation(value = "Returns policy types")
     @ApiResponses(value = {@ApiResponse(code = 200, message = "Policy Types found")})
     public ResponseEntity<String> getPolicyTypes(@RequestParam(name = "ric", required = false) String ricName) {
-        if (ricName == null) {
-            Collection<PolicyType> types = this.policyTypes.getAll();
-            return new ResponseEntity<String>(toPolicyTypeIdsJson(types), HttpStatus.OK);
-        } else {
-            try {
-                Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
+        synchronized (this.policyTypes) {
+            if (ricName == null) {
+                Collection<PolicyType> types = this.policyTypes.getAll();
                 return new ResponseEntity<String>(toPolicyTypeIdsJson(types), HttpStatus.OK);
-            } catch (ServiceException e) {
-                return new ResponseEntity<String>(e.toString(), HttpStatus.NOT_FOUND);
+            } else {
+                try {
+                    Collection<PolicyType> types = rics.getRic(ricName).getSupportedPolicyTypes();
+                    return new ResponseEntity<String>(toPolicyTypeIdsJson(types), HttpStatus.OK);
+                } catch (ServiceException e) {
+                    return new ResponseEntity<String>(e.toString(), HttpStatus.NOT_FOUND);
+                }
             }
         }
     }
@@ -140,7 +144,7 @@ public class PolicyController {
     public Mono<ResponseEntity<Void>> deletePolicy( //
         @RequestParam(name = "instance", required = true) String id) {
         Policy policy = policies.get(id);
-        if (policy != null && policy.ric().state().equals(Ric.RicState.ACTIVE)) {
+        if (policy != null && policy.ric().state().equals(Ric.RicState.IDLE)) {
             return a1Client.deletePolicy(policy.ric().getConfig().baseUrl(), id) //
                 .doOnEach(notUsed -> policies.removeId(id)) //
                 .flatMap(notUsed -> {
@@ -163,7 +167,7 @@ public class PolicyController {
 
         Ric ric = rics.get(ricName);
         PolicyType type = policyTypes.get(typeName);
-        if (ric != null && type != null && ric.state().equals(Ric.RicState.ACTIVE)) {
+        if (ric != null && type != null && ric.state().equals(Ric.RicState.IDLE)) {
             Policy policy = ImmutablePolicy.builder() //
                 .id(instanceId) //
                 .json(jsonBody) //
@@ -172,7 +176,7 @@ public class PolicyController {
                 .ownerServiceName(service) //
                 .lastModified(getTimeStampUTC()) //
                 .build();
-            return a1Client.putPolicy(policy.ric().getConfig().baseUrl(), policy.id(), policy.json()) //
+            return a1Client.putPolicy(policy) //
                 .doOnNext(notUsed -> policies.put(policy)) //
                 .flatMap(notUsed -> {
                     return Mono.just(new ResponseEntity<>(HttpStatus.CREATED));
@@ -189,22 +193,24 @@ public class PolicyController {
         @RequestParam(name = "ric", required = false) String ric, //
         @RequestParam(name = "service", required = false) String service) //
     {
-        Collection<Policy> result = null;
+        synchronized (policies) {
+            Collection<Policy> result = null;
 
-        if (type != null) {
-            result = policies.getForType(type);
-            result = filter(result, null, ric, service);
-        } else if (service != null) {
-            result = policies.getForService(service);
-            result = filter(result, type, ric, null);
-        } else if (ric != null) {
-            result = policies.getForRic(ric);
-            result = filter(result, type, null, service);
-        } else {
-            result = policies.getAll();
-        }
+            if (type != null) {
+                result = policies.getForType(type);
+                result = filter(result, null, ric, service);
+            } else if (service != null) {
+                result = policies.getForService(service);
+                result = filter(result, type, ric, null);
+            } else if (ric != null) {
+                result = policies.getForRic(ric);
+                result = filter(result, type, null, service);
+            } else {
+                result = policies.getAll();
+            }
 
-        return new ResponseEntity<String>(policiesToJson(result), HttpStatus.OK);
+            return new ResponseEntity<String>(policiesToJson(result), HttpStatus.OK);
+        }
     }
 
     private boolean include(String filter, String value) {
index 797ec71..6b413b2 100644 (file)
@@ -94,14 +94,17 @@ public class RicRepositoryController {
         })
     public ResponseEntity<String> getRics(
         @RequestParam(name = "policyType", required = false) String supportingPolicyType) {
+
         Vector<RicInfo> result = new Vector<>();
-        for (Ric ric : rics.getRics()) {
-            if (supportingPolicyType == null || ric.isSupportingType(supportingPolicyType)) {
-                result.add(ImmutableRicInfo.builder() //
-                    .name(ric.name()) //
-                    .managedElementIds(ric.getManagedElementIds()) //
-                    .policyTypes(ric.getSupportedPolicyTypeNames()) //
-                    .build());
+        synchronized (rics) {
+            for (Ric ric : rics.getRics()) {
+                if (supportingPolicyType == null || ric.isSupportingType(supportingPolicyType)) {
+                    result.add(ImmutableRicInfo.builder() //
+                        .name(ric.name()) //
+                        .managedElementIds(ric.getManagedElementIds()) //
+                        .policyTypes(ric.getSupportedPolicyTypeNames()) //
+                        .build());
+                }
             }
         }
 
index 6831d4c..bda5e09 100644 (file)
@@ -86,15 +86,16 @@ public class ServiceController {
     }
 
     private Service toService(ServiceRegistrationInfo s) {
-        return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval()));
+        return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval()), s.callbackUrl());
     }
 
     @GetMapping("/services")
     public ResponseEntity<?> getServices() {
-        Collection<Service> allServices = this.services.getAll();
-        Collection<ServiceStatus> result = new Vector<>(allServices.size());
-        for (Service s : allServices) {
-            result.add(toServiceStatus(s));
+        Collection<ServiceStatus> result = new Vector<>();
+        synchronized (this.services) {
+            for (Service s : this.services.getAll()) {
+                result.add(toServiceStatus(s));
+            }
         }
         return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
     }
index 58c91b3..a279db5 100644 (file)
@@ -21,6 +21,7 @@
 package org.oransc.policyagent.repository;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
@@ -68,7 +69,7 @@ public class Policies {
         if (map == null) {
             return new Vector<Policy>();
         }
-        return map.values();
+        return Collections.unmodifiableCollection(map.values());
     }
 
     public synchronized boolean containsPolicy(String id) {
@@ -88,7 +89,7 @@ public class Policies {
     }
 
     public synchronized Collection<Policy> getAll() {
-        return policiesId.values();
+        return Collections.unmodifiableCollection(policiesId.values());
     }
 
     public synchronized Collection<Policy> getForService(String service) {
index 9dee6f9..7723983 100644 (file)
@@ -21,6 +21,7 @@
 package org.oransc.policyagent.repository;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -48,19 +49,19 @@ public class PolicyTypes {
         types.put(type.name(), type);
     }
 
-    public boolean contains(String policyType) {
+    public synchronized boolean contains(String policyType) {
         return types.containsKey(policyType);
     }
 
     public synchronized Collection<PolicyType> getAll() {
-        return types.values();
+        return Collections.unmodifiableCollection(types.values());
     }
 
-    public int size() {
+    public synchronized int size() {
         return types.size();
     }
 
-    public void clear() {
+    public synchronized void clear() {
         this.types.clear();
     }
 }
index 82d84f1..235ee1a 100644 (file)
@@ -32,7 +32,7 @@ import org.oransc.policyagent.configuration.RicConfig;
  */
 public class Ric {
     private final RicConfig ricConfig;
-    private RicState state = RicState.NOT_INITIATED;
+    private RicState state = RicState.UNDEFINED;
     private Map<String, PolicyType> supportedPolicyTypes = new HashMap<>();
 
     /**
@@ -150,16 +150,16 @@ public class Ric {
      */
     public static enum RicState {
         /**
-         * The Ric has not been initiated yet.
+         * The agent view of the agent may be inconsistent
          */
-        NOT_INITIATED,
+        UNDEFINED,
         /**
-         * The Ric is working fine.
+         * The normal state. Policies can be configured.
          */
-        ACTIVE,
+        IDLE,
         /**
-         * The Ric cannot be contacted.
+         * The Ric states are recovered
          */
-        NOT_REACHABLE, RECOVERING
+        RECOVERING
     }
 }
index 6b8138f..bdf9930 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.oransc.policyagent.repository;
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -36,11 +35,11 @@ public class Rics {
         rics.put(ric.name(), ric);
     }
 
-    public Collection<Ric> getRics() {
+    public synchronized Iterable<Ric> getRics() {
         return rics.values();
     }
 
-    public Ric getRic(String name) throws ServiceException {
+    public synchronized Ric getRic(String name) throws ServiceException {
         Ric ric = rics.get(name);
         if (ric == null) {
             throw new ServiceException("Could not find ric: " + name);
@@ -48,15 +47,19 @@ public class Rics {
         return ric;
     }
 
-    public Ric get(String name) {
+    public synchronized Ric get(String name) {
         return rics.get(name);
     }
 
-    public int size() {
+    public synchronized void remove(String name) {
+        rics.remove(name);
+    }
+
+    public synchronized int size() {
         return rics.size();
     }
 
-    public void clear() {
+    public synchronized void clear() {
         this.rics.clear();
     }
 }
index 81ef7ff..6458dbb 100644 (file)
@@ -27,11 +27,12 @@ public class Service {
     private final String name;
     private final Duration keepAliveInterval;
     private Instant lastPing;
-    // private final String callbackUrl1; // TBD
+    private final String callbackUrl;
 
-    public Service(String name, Duration keepAliveInterval) {
+    public Service(String name, Duration keepAliveInterval, String callbackUrl) {
         this.name = name;
         this.keepAliveInterval = keepAliveInterval;
+        this.callbackUrl = callbackUrl;
         ping();
     }
 
@@ -55,4 +56,8 @@ public class Service {
         return Duration.between(this.lastPing, Instant.now());
     }
 
+    public synchronized String getCallbackUrl() {
+        return this.callbackUrl;
+    }
+
 }
index 509b2f5..2e1d8da 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.oransc.policyagent.repository;
 
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -53,7 +52,7 @@ public class Services {
         services.put(service.getName(), service);
     }
 
-    public synchronized Collection<Service> getAll() {
+    public synchronized Iterable<Service> getAll() {
         return services.values();
     }
 
index 9ac9d70..1a90382 100644 (file)
@@ -26,7 +26,9 @@ import org.oransc.policyagent.clients.A1Client;
 import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
+import org.oransc.policyagent.repository.Ric.RicState;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Services;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -49,13 +51,16 @@ public class RepositorySupervision {
     private final Policies policies;
     private final PolicyTypes policyTypes;
     private final A1Client a1Client;
+    private final Services services;
 
     @Autowired
-    public RepositorySupervision(Rics rics, Policies policies, A1Client a1Client, PolicyTypes policyTypes) {
+    public RepositorySupervision(Rics rics, Policies policies, A1Client a1Client, PolicyTypes policyTypes,
+        Services services) {
         this.rics = rics;
         this.policies = policies;
         this.a1Client = a1Client;
         this.policyTypes = policyTypes;
+        this.services = services;
     }
 
     /**
@@ -65,29 +70,38 @@ public class RepositorySupervision {
     public void checkAllRics() {
         logger.debug("Checking Rics starting");
         createTask().subscribe(this::onRicChecked, this::onError, this::onComplete);
-
     }
 
     private Flux<Ric> createTask() {
-        return Flux.fromIterable(rics.getRics()) //
-            .flatMap(ric -> checkInstances(ric)) //
-            .flatMap(ric -> checkTypes(ric));
+        synchronized (this.rics) {
+            return Flux.fromIterable(rics.getRics()) //
+                .flatMap(ric -> checkRicState(ric)) //
+                .flatMap(ric -> checkRicPolicies(ric)) //
+                .flatMap(ric -> checkRicPolicyTypes(ric));
+        }
     }
 
-    private Mono<Ric> checkInstances(Ric ric) {
+    private Mono<Ric> checkRicState(Ric ric) {
+        if (ric.state() == RicState.UNDEFINED) {
+            return startRecovery(ric);
+        } else if (ric.state() == RicState.RECOVERING) {
+            return Mono.empty();
+        } else {
+            return Mono.just(ric);
+        }
+    }
 
+    private Mono<Ric> checkRicPolicies(Ric ric) {
         return a1Client.getPolicyIdentities(ric.getConfig().baseUrl()) //
             .onErrorResume(t -> Mono.empty()) //
             .flatMap(ricP -> validateInstances(ricP, ric));
     }
 
-    private Flux<Ric> junk() {
-        return Flux.empty();
-    }
-
     private Mono<Ric> validateInstances(Collection<String> ricPolicies, Ric ric) {
-        if (ricPolicies.size() != policies.getForRic(ric.name()).size()) {
-            return startRecovery(ric);
+        synchronized (this.policies) {
+            if (ricPolicies.size() != policies.getForRic(ric.name()).size()) {
+                return startRecovery(ric);
+            }
         }
         for (String policyId : ricPolicies) {
             if (!policies.containsPolicy(policyId)) {
@@ -97,7 +111,7 @@ public class RepositorySupervision {
         return Mono.just(ric);
     }
 
-    private Mono<Ric> checkTypes(Ric ric) {
+    private Mono<Ric> checkRicPolicyTypes(Ric ric) {
         return a1Client.getPolicyTypeIdentities(ric.getConfig().baseUrl()) //
             .onErrorResume(t -> {
                 return Mono.empty();
@@ -118,7 +132,7 @@ public class RepositorySupervision {
     }
 
     private Mono<Ric> startRecovery(Ric ric) {
-        RicRecoveryTask recovery = new RicRecoveryTask(a1Client, policyTypes, policies);
+        RicRecoveryTask recovery = new RicRecoveryTask(a1Client, policyTypes, policies, services);
         recovery.run(ric);
         return Mono.empty();
     }
index 3883585..fb41e26 100644 (file)
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Vector;
 
 import org.oransc.policyagent.clients.A1Client;
+import org.oransc.policyagent.clients.AsyncRestClient;
 import org.oransc.policyagent.exceptions.ServiceException;
 import org.oransc.policyagent.repository.ImmutablePolicyType;
 import org.oransc.policyagent.repository.Policies;
@@ -31,6 +32,9 @@ import org.oransc.policyagent.repository.Policy;
 import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
+import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Service;
+import org.oransc.policyagent.repository.Services;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,16 +51,20 @@ public class RicRecoveryTask {
     private final A1Client a1Client;
     private final PolicyTypes policyTypes;
     private final Policies policies;
+    private final Services services;
 
-    public RicRecoveryTask(A1Client a1Client, PolicyTypes policyTypes, Policies policies) {
+    public RicRecoveryTask(A1Client a1Client, PolicyTypes policyTypes, Policies policies, Services services) {
         this.a1Client = a1Client;
         this.policyTypes = policyTypes;
         this.policies = policies;
+        this.services = services;
     }
 
-    public void run(Collection<Ric> rics) {
-        for (Ric ric : rics) {
-            run(ric);
+    public void run(Rics rics) {
+        synchronized (rics) {
+            for (Ric ric : rics.getRics()) {
+                run(ric);
+            }
         }
     }
 
@@ -80,20 +88,39 @@ public class RicRecoveryTask {
 
     private void onComplete(Ric ric) {
         logger.debug("Recovery completed for:" + ric.name());
-        ric.setState(Ric.RicState.ACTIVE);
+        ric.setState(Ric.RicState.IDLE);
+        notifyAllServices("Recovery completed for:" + ric.name());
+    }
 
+    private void notifyAllServices(String body) {
+        synchronized (services) {
+            for (Service service : services.getAll()) {
+                String url = service.getCallbackUrl();
+                if (service.getCallbackUrl().length() > 0) {
+                    createClient(url) //
+                        .put("", body) //
+                        .subscribe(rsp -> logger.debug("Service called"),
+                            throwable -> logger.warn("Service called failed", throwable),
+                            () -> logger.debug("Service called complete"));
+                }
+            }
+        }
     }
 
     private void onError(Ric ric, Throwable t) {
-        logger.debug("Recovery failed for: {}, reason: {}", ric.name(), t.getMessage());
-        ric.setState(Ric.RicState.NOT_REACHABLE);
+        logger.warn("Recovery failed for: {}, reason: {}", ric.name(), t.getMessage());
+        ric.setState(Ric.RicState.UNDEFINED);
+    }
+
+    private AsyncRestClient createClient(final String url) {
+        return new AsyncRestClient(url);
     }
 
     private Flux<PolicyType> recoverPolicyTypes(Ric ric) {
         ric.clearSupportedPolicyTypes();
         return a1Client.getPolicyTypeIdentities(ric.getConfig().baseUrl()) //
             .flatMapMany(types -> Flux.fromIterable(types)) //
-            .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), typeId))
+            .doOnNext(typeId -> logger.debug("For ric: {}, handling type: {}", ric.getConfig().name(), typeId)) //
             .flatMap((policyTypeId) -> getPolicyType(ric, policyTypeId)) //
             .doOnNext(policyType -> ric.addSupportedPolicyType(policyType)); //
     }
@@ -117,9 +144,11 @@ public class RicRecoveryTask {
     }
 
     private Flux<String> deletePolicies(Ric ric) {
-        Collection<Policy> ricPolicies = new Vector<>(policies.getForRic(ric.name()));
-        for (Policy policy : ricPolicies) {
-            this.policies.remove(policy);
+        synchronized (policies) {
+            Collection<Policy> ricPolicies = new Vector<>(policies.getForRic(ric.name()));
+            for (Policy policy : ricPolicies) {
+                this.policies.remove(policy);
+            }
         }
 
         return a1Client.getPolicyIdentities(ric.getConfig().baseUrl()) //
index 335aa94..1e7f2dc 100644 (file)
@@ -69,16 +69,20 @@ public class ServiceSupervision {
     }
 
     private Flux<Policy> createTask() {
-        return Flux.fromIterable(services.getAll()) //
-            .filter(service -> service.isExpired()) //
-            .doOnNext(service -> logger.info("Service is expired:" + service.getName())) //
-            .flatMap(service -> getAllPolicies(service)) //
-            .doOnNext(policy -> this.policies.remove(policy)) //
-            .flatMap(policy -> deletePolicyInRic(policy));
+        synchronized (services) {
+            return Flux.fromIterable(services.getAll()) //
+                .filter(service -> service.isExpired()) //
+                .doOnNext(service -> logger.info("Service is expired:" + service.getName())) //
+                .flatMap(service -> getAllPolicies(service)) //
+                .doOnNext(policy -> this.policies.remove(policy)) //
+                .flatMap(policy -> deletePolicyInRic(policy));
+        }
     }
 
     private Flux<Policy> getAllPolicies(Service service) {
-        return Flux.fromIterable(policies.getForService(service.getName()));
+        synchronized (policies) {
+            return Flux.fromIterable(policies.getForService(service.getName()));
+        }
     }
 
     private Mono<Policy> deletePolicyInRic(Policy policy) {
index d2356ea..90358b2 100644 (file)
@@ -27,16 +27,20 @@ import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Services;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 /**
  * Loads information about RealTime-RICs at startup.
  */
 @Service("startupService")
-public class StartupService {
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class StartupService implements ApplicationConfig.Observer {
 
     private static final Logger logger = LoggerFactory.getLogger(StartupService.class);
 
@@ -55,13 +59,35 @@ public class StartupService {
     @Autowired
     private Policies policies;
 
+    @Autowired
+    private Services services;
+
+    // Only for unittesting
     StartupService(ApplicationConfig appConfig, Rics rics, PolicyTypes policyTypes, A1Client a1Client,
-        Policies policies) {
+        Policies policies, Services services) {
         this.applicationConfig = appConfig;
         this.rics = rics;
         this.policyTypes = policyTypes;
         this.a1Client = a1Client;
         this.policies = policies;
+        this.services = services;
+    }
+
+    @Override
+    public void onRicConfigUpdate(RicConfig ricConfig, ApplicationConfig.RicConfigUpdate event) {
+        synchronized (this.rics) {
+            if (event.equals(ApplicationConfig.RicConfigUpdate.ADDED)
+                || event.equals(ApplicationConfig.RicConfigUpdate.CHANGED)) {
+                Ric ric = new Ric(ricConfig);
+                rics.put(ric);
+                RicRecoveryTask recoveryTask = new RicRecoveryTask(a1Client, policyTypes, policies, services);
+                recoveryTask.run(ric);
+            } else if (event.equals(ApplicationConfig.RicConfigUpdate.REMOVED)) {
+                rics.remove(ricConfig.name());
+            } else {
+                logger.debug("Unhandled event :" + event);
+            }
+        }
     }
 
     /**
@@ -69,12 +95,8 @@ public class StartupService {
      */
     public void startup() {
         logger.debug("Starting up");
+        applicationConfig.addObserver(this);
         applicationConfig.initialize();
-        for (RicConfig ricConfig : applicationConfig.getRicConfigs()) {
-            rics.put(new Ric(ricConfig));
-        }
-        RicRecoveryTask recoveryTask = new RicRecoveryTask(a1Client, policyTypes, policies);
-        recoveryTask.run(rics.getRics()); // recover all Rics
     }
 
 }
index 365d418..d78155d 100644 (file)
@@ -29,7 +29,6 @@ import com.google.gson.GsonBuilder;
 import com.google.gson.reflect.TypeToken;
 
 import java.net.URL;
-import java.util.Collection;
 import java.util.List;
 import java.util.Vector;
 
@@ -52,6 +51,7 @@ import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.utils.MockA1Client;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -63,7 +63,6 @@ import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import org.springframework.web.client.RestTemplate;
-import reactor.core.publisher.Mono;
 
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@@ -86,52 +85,9 @@ public class ApplicationTest {
 
     public static class MockApplicationConfig extends ApplicationConfig {
         @Override
-        public void initialize() {
+        protected String getLocalConfigurationFilePath() {
             URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json");
-            loadConfigurationFromFile(url.getFile());
-        }
-    }
-
-    static class A1ClientMock implements A1Client {
-        private final Policies policies;
-        private final PolicyTypes policyTypes;
-
-        A1ClientMock(Policies policies, PolicyTypes policyTypes) {
-            this.policies = policies;
-            this.policyTypes = policyTypes;
-        }
-
-        @Override
-        public Mono<Collection<String>> getPolicyTypeIdentities(String nearRtRicUrl) {
-            Vector<String> result = new Vector<>();
-            for (PolicyType p : this.policyTypes.getAll()) {
-                result.add(p.name());
-            }
-            return Mono.just(result);
-        }
-
-        @Override
-        public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId) {
-            try {
-                return Mono.just(this.policies.get(policyTypeId).json());
-            } catch (Exception e) {
-                return Mono.error(e);
-            }
-        }
-
-        @Override
-        public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
-            return Mono.just("OK");
-        }
-
-        @Override
-        public Mono<String> deletePolicy(String nearRtRicUrl, String policyId) {
-            return Mono.just("OK");
-        }
-
-        @Override
-        public Mono<Collection<String>> getPolicyIdentities(String nearRtRicUrl) {
-            return Mono.empty(); // problem is that a recovery will start
+            return url.getFile();
         }
     }
 
@@ -151,7 +107,7 @@ public class ApplicationTest {
 
         @Bean
         A1Client getA1Client() {
-            return new A1ClientMock(this.policies, this.policyTypes);
+            return new MockA1Client(this.policyTypes);
         }
 
         @Bean
@@ -212,7 +168,7 @@ public class ApplicationTest {
         String url = baseUrl() + "/policy?type=type1&instance=instance1&ric=ric1&service=service1";
         String json = "{}";
         addPolicyType("type1", "ric1");
-        this.rics.getRic("ric1").setState(Ric.RicState.ACTIVE);
+        this.rics.getRic("ric1").setState(Ric.RicState.IDLE);
 
         this.restTemplate.put(url, json);
 
@@ -293,7 +249,7 @@ public class ApplicationTest {
         reset();
         String url = baseUrl() + "/policy?instance=id";
         Policy policy = addPolicy("id", "typeName", "service1", "ric1");
-        policy.ric().setState(Ric.RicState.ACTIVE);
+        policy.ric().setState(Ric.RicState.IDLE);
         assertThat(policies.size()).isEqualTo(1);
 
         this.restTemplate.delete(url);
@@ -397,6 +353,7 @@ public class ApplicationTest {
         ServiceRegistrationInfo service = ImmutableServiceRegistrationInfo.builder() //
             .keepAliveInterval(1) //
             .name(name) //
+            .callbackUrl("callbackUrl") //
             .build();
         String json = gson.toJson(service);
         return json;
index dd57710..ecb4661 100644 (file)
@@ -27,10 +27,6 @@ import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 import java.nio.file.Files;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
 
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -41,103 +37,64 @@ import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Rics;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.oransc.policyagent.utils.MockA1Client;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 import org.springframework.boot.test.context.TestConfiguration;
 import org.springframework.boot.web.server.LocalServerPort;
 import org.springframework.context.annotation.Bean;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
-import reactor.core.publisher.Mono;
 
 @ExtendWith(SpringExtension.class)
 @SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
 public class MockPolicyAgent {
 
-    @Autowired
-    private Rics rics;
-
-    @Autowired
-    private Policies policies;
-
-    @Autowired
-    private PolicyTypes policyTypes;
-
     static class MockApplicationConfig extends ApplicationConfig {
 
         @Override
-        public void initialize() {
+        protected String getLocalConfigurationFilePath() {
             URL url = MockApplicationConfig.class.getClassLoader().getResource("test_application_configuration.json");
-            loadConfigurationFromFile(url.getFile());
-        }
-    }
-
-    private static class RicPolicyDatabase {
-        private Map<String, Map<String, String>> policies = new HashMap<>();
-
-        public void putPolicy(String nearRtRicUrl, String policyId, String policyString) {
-            getPolicies(nearRtRicUrl).put(policyId, policyString);
+            return url.getFile();
         }
 
-        public Collection<String> getPolicyIdentities(String nearRtRicUrl) {
-            return getPolicies(nearRtRicUrl).keySet();
-        }
-
-        public void deletePolicy(String nearRtRicUrl, String policyId) {
-            getPolicies(nearRtRicUrl).remove(policyId);
-        }
-
-        private Map<String, String> getPolicies(String nearRtRicUrl) {
-            if (!policies.containsKey(nearRtRicUrl)) {
-                policies.put(nearRtRicUrl, new HashMap<>());
-            }
-            return policies.get(nearRtRicUrl);
-        }
     }
 
-    static class A1ClientMock implements A1Client {
+    /**
+     * overrides the BeanFactory
+     */
+    @TestConfiguration
+    static class TestBeanFactory {
 
-        private final RicPolicyDatabase policies = new RicPolicyDatabase();
+        private final Rics rics = new Rics();
+        private final Policies policies = new Policies();
         private final PolicyTypes policyTypes = new PolicyTypes();
 
-        A1ClientMock() {
-            loadTypes(this.policyTypes);
-        }
-
-        @Override
-        public Mono<Collection<String>> getPolicyTypeIdentities(String nearRtRicUrl) {
-            Vector<String> result = new Vector<>();
-            for (PolicyType p : this.policyTypes.getAll()) {
-                result.add(p.name());
-            }
-            return Mono.just(result);
+        @Bean
+        public ApplicationConfig getApplicationConfig() {
+            return new MockApplicationConfig();
         }
 
-        @Override
-        public Mono<Collection<String>> getPolicyIdentities(String nearRtRicUrl) {
-            Collection<String> result = policies.getPolicyIdentities(nearRtRicUrl);
-            return Mono.just(result);
+        @Bean
+        public A1Client getA1Client() {
+            PolicyTypes ricTypes = new PolicyTypes();
+            loadTypes(ricTypes);
+            A1Client client = new MockA1Client(ricTypes);
+            return client;
         }
 
-        @Override
-        public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId) {
-            try {
-                return Mono.just(this.policyTypes.getType(policyTypeId).schema());
-            } catch (Exception e) {
-                return Mono.error(e);
-            }
+        @Bean
+        public Policies getPolicies() {
+            return this.policies;
         }
 
-        @Override
-        public Mono<String> putPolicy(String nearRtRicUrl, String policyId, String policyString) {
-            policies.putPolicy(nearRtRicUrl, policyId, policyString);
-            return Mono.just("OK");
+        @Bean
+        public PolicyTypes getPolicyTypes() {
+            return this.policyTypes;
         }
 
-        @Override
-        public Mono<String> deletePolicy(String nearRtRicUrl, String policyId) {
-            policies.deletePolicy(nearRtRicUrl, policyId);
-            return Mono.just("OK");
+        @Bean
+        public Rics getRics() {
+            return this.rics;
         }
 
         private static File[] getResourceFolderFiles(String folder) {
@@ -164,42 +121,7 @@ public class MockPolicyAgent {
                 }
             }
         }
-    }
 
-    /**
-     * overrides the BeanFactory
-     */
-    @TestConfiguration
-    static class TestBeanFactory {
-
-        private final Rics rics = new Rics();
-        private final Policies policies = new Policies();
-        private final PolicyTypes policyTypes = new PolicyTypes();
-
-        @Bean
-        public ApplicationConfig getApplicationConfig() {
-            return new MockApplicationConfig();
-        }
-
-        @Bean
-        A1Client getA1Client() {
-            return new A1ClientMock();
-        }
-
-        @Bean
-        public Policies getPolicies() {
-            return this.policies;
-        }
-
-        @Bean
-        public PolicyTypes getPolicyTypes() {
-            return this.policyTypes;
-        }
-
-        @Bean
-        public Rics getRics() {
-            return this.rics;
-        }
     }
 
     @LocalServerPort
index f9a93c8..b3b5f48 100644 (file)
 
 package org.oransc.policyagent.clients;
 
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import java.util.Arrays;
+import java.util.Vector;
 
 import org.json.JSONException;
 import org.junit.jupiter.api.BeforeEach;
@@ -35,6 +37,13 @@ import org.mockito.Mock;
 import org.mockito.Spy;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.junit.jupiter.MockitoExtension;
+import org.oransc.policyagent.configuration.ImmutableRicConfig;
+import org.oransc.policyagent.configuration.RicConfig;
+import org.oransc.policyagent.repository.ImmutablePolicy;
+import org.oransc.policyagent.repository.ImmutablePolicyType;
+import org.oransc.policyagent.repository.Policy;
+import org.oransc.policyagent.repository.PolicyType;
+import org.oransc.policyagent.repository.Ric;
 
 import reactor.core.publisher.Mono;
 import reactor.test.StepVerifier;
@@ -56,6 +65,7 @@ public class A1ClientImplTest {
     private static final String POLICY_2_ID = "policy2";
     private static final String POLICY_JSON_VALID = "{\"policyId\":\"policy1\"}";
     private static final String POLICY_JSON_INVALID = "\"policyId\":\"policy1\"}";
+    private static final String POLICY_TYPE = "typeName";
 
     @Spy
     A1ClientImpl a1Client;
@@ -111,24 +121,46 @@ public class A1ClientImplTest {
 
     @Test
     public void testPutPolicyValidResponse() {
-        when(asyncRestClientMock.put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID))
-            .thenReturn(Mono.just(POLICY_JSON_VALID));
+        when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON_VALID));
 
-        Mono<String> policyMono = a1Client.putPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID);
+        Mono<String> policyMono =
+            a1Client.putPolicy(createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE));
         verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID);
         StepVerifier.create(policyMono).expectNext(POLICY_JSON_VALID).expectComplete().verify();
     }
 
     @Test
     public void testPutPolicyInvalidResponse() {
-        when(asyncRestClientMock.put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID))
-            .thenReturn(Mono.just(POLICY_JSON_INVALID));
+        when(asyncRestClientMock.put(anyString(), anyString())).thenReturn(Mono.just(POLICY_JSON_INVALID));
 
-        Mono<String> policyMono = a1Client.putPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID);
-        verify(asyncRestClientMock).put(POLICIES_URL + POLICY_1_ID, POLICY_JSON_VALID);
+        Mono<String> policyMono =
+            a1Client.putPolicy(createPolicy(RIC_URL, POLICY_1_ID, POLICY_JSON_VALID, POLICY_TYPE));
         StepVerifier.create(policyMono).expectErrorMatches(throwable -> throwable instanceof JSONException).verify();
     }
 
+    private Policy createPolicy(String nearRtRicUrl, String policyId, String json, String type) {
+        return ImmutablePolicy.builder() //
+            .id(policyId) //
+            .json(json) //
+            .ownerServiceName("service") //
+            .ric(createRic(nearRtRicUrl)) //
+            .type(createPolicyType(type)) //
+            .lastModified("now") //
+            .build();
+    }
+
+    private PolicyType createPolicyType(String name) {
+        return ImmutablePolicyType.builder().name(name).schema("schema").build();
+    }
+
+    private Ric createRic(String url) {
+        RicConfig cfg = ImmutableRicConfig.builder().name("ric") //
+            .baseUrl(url) //
+            .managedElementIds(new Vector<String>(Arrays.asList("kista_1", "kista_2"))) //
+            .build();
+        return new Ric(cfg);
+    }
+
     @Test
     public void testDeletePolicy() {
         when(asyncRestClientMock.delete(POLICIES_URL + POLICY_1_ID)).thenReturn(Mono.empty());
index 9cfb616..6a4f8b3 100644 (file)
@@ -96,13 +96,14 @@ public class ApplicationConfigTest {
         appConfigUnderTest.systemEnvironment = new Properties();
         // When
         doReturn(getCorrectJson()).when(appConfigUnderTest).createInputStream(any());
+        doReturn("fileName").when(appConfigUnderTest).getLocalConfigurationFilePath();
         appConfigUnderTest.initialize();
 
         // Then
-        verify(appConfigUnderTest, times(1)).loadConfigurationFromFile(any());
+        verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
 
-        Vector<RicConfig> ricConfigs = appConfigUnderTest.getRicConfigs();
-        RicConfig ricConfig = ricConfigs.firstElement();
+        Iterable<RicConfig> ricConfigs = appConfigUnderTest.getRicConfigs();
+        RicConfig ricConfig = ricConfigs.iterator().next();
         assertThat(ricConfigs).isNotNull();
         assertThat(ricConfig).isEqualTo(CORRECT_RIC_CONIFG);
     }
@@ -115,11 +116,12 @@ public class ApplicationConfigTest {
 
         // When
         doReturn(getIncorrectJson()).when(appConfigUnderTest).createInputStream(any());
-        appConfigUnderTest.loadConfigurationFromFile(any());
+        doReturn("fileName").when(appConfigUnderTest).getLocalConfigurationFilePath();
+        appConfigUnderTest.loadConfigurationFromFile();
 
         // Then
-        verify(appConfigUnderTest, times(1)).loadConfigurationFromFile(any());
-        Assertions.assertNull(appConfigUnderTest.getRicConfigs());
+        verify(appConfigUnderTest, times(1)).loadConfigurationFromFile();
+        Assertions.assertEquals(0, appConfigUnderTest.getRicConfigs().size());
     }
 
     @Test
index 791acee..b1f397a 100644 (file)
@@ -47,6 +47,7 @@ import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Ric.RicState;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Services;
 import reactor.core.publisher.Mono;
 
 @ExtendWith(MockitoExtension.class)
@@ -62,13 +63,13 @@ public class RepositorySupervisionTest {
             .baseUrl("baseUrl1") //
             .managedElementIds(new Vector<String>(Arrays.asList("kista_1", "kista_2"))) //
             .build());
-        ric1.setState(Ric.RicState.ACTIVE);
+        ric1.setState(Ric.RicState.IDLE);
         Ric ric2 = new Ric(ImmutableRicConfig.builder() //
             .name("ric2") //
             .baseUrl("baseUrl2") //
             .managedElementIds(new Vector<String>(Arrays.asList("kista_3", "kista_4"))) //
             .build());
-        ric2.setState(Ric.RicState.NOT_REACHABLE);
+        ric2.setState(Ric.RicState.UNDEFINED);
         Ric ric3 = new Ric(ImmutableRicConfig.builder() //
             .name("ric3") //
             .baseUrl("baseUrl3") //
@@ -94,8 +95,10 @@ public class RepositorySupervisionTest {
         Policies policies = new Policies();
         policies.put(policy1);
         PolicyTypes types = new PolicyTypes();
+        Services services = new Services();
 
-        RepositorySupervision supervisorUnderTest = new RepositorySupervision(rics, policies, a1ClientMock, types);
+        RepositorySupervision supervisorUnderTest =
+            new RepositorySupervision(rics, policies, a1ClientMock, types, services);
 
         Mono<Collection<String>> policyIds = Mono.just(Arrays.asList("policyId1", "policyId2"));
         when(a1ClientMock.getPolicyIdentities(anyString())).thenReturn(policyIds);
@@ -105,9 +108,9 @@ public class RepositorySupervisionTest {
 
         supervisorUnderTest.checkAllRics();
 
-        await().untilAsserted(() -> RicState.ACTIVE.equals(ric1.state()));
-        await().untilAsserted(() -> RicState.ACTIVE.equals(ric2.state()));
-        await().untilAsserted(() -> RicState.ACTIVE.equals(ric3.state()));
+        await().untilAsserted(() -> RicState.IDLE.equals(ric1.state()));
+        await().untilAsserted(() -> RicState.IDLE.equals(ric2.state()));
+        await().untilAsserted(() -> RicState.IDLE.equals(ric3.state()));
 
         verify(a1ClientMock).deletePolicy("baseUrl1", "policyId2");
         verify(a1ClientMock).deletePolicy("baseUrl2", "policyId2");
index 0c254d5..729fc7b 100644 (file)
@@ -29,8 +29,7 @@ import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
-import static org.oransc.policyagent.repository.Ric.RicState.ACTIVE;
-import static org.oransc.policyagent.repository.Ric.RicState.NOT_REACHABLE;
+import static org.oransc.policyagent.repository.Ric.RicState.IDLE;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -49,7 +48,9 @@ import org.oransc.policyagent.configuration.RicConfig;
 import org.oransc.policyagent.repository.Policies;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
+import org.oransc.policyagent.repository.Ric.RicState;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Services;
 import reactor.core.publisher.Mono;
 
 @ExtendWith(MockitoExtension.class)
@@ -76,11 +77,6 @@ public class StartupServiceTest {
 
     @Test
     public void startup_allOk() {
-        Vector<RicConfig> ricConfigs = new Vector<>(2);
-        ricConfigs.add(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A));
-        ricConfigs.add(getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C));
-        when(appConfigMock.getRicConfigs()).thenReturn(ricConfigs);
-
         Mono<Collection<String>> policyTypes1 = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME));
         Mono<Collection<String>> policyTypes2 = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME, POLICY_TYPE_2_NAME));
         when(a1ClientMock.getPolicyTypeIdentities(anyString())).thenReturn(policyTypes1).thenReturn(policyTypes2);
@@ -92,10 +88,16 @@ public class StartupServiceTest {
         Rics rics = new Rics();
         PolicyTypes policyTypes = new PolicyTypes();
         StartupService serviceUnderTest =
-            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies());
+            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services());
 
         serviceUnderTest.startup();
 
+        serviceUnderTest.onRicConfigUpdate(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A),
+            ApplicationConfig.RicConfigUpdate.ADDED);
+        serviceUnderTest.onRicConfigUpdate(
+            getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C),
+            ApplicationConfig.RicConfigUpdate.ADDED);
+
         await().untilAsserted(() -> assertThat(policyTypes.size()).isEqualTo(2));
 
         verify(a1ClientMock).getPolicyTypeIdentities(FIRST_RIC_URL);
@@ -113,7 +115,7 @@ public class StartupServiceTest {
         Ric firstRic = rics.get(FIRST_RIC_NAME);
         assertNotNull(firstRic, "Ric " + FIRST_RIC_NAME + " not added to repository");
         assertEquals(FIRST_RIC_NAME, firstRic.name(), FIRST_RIC_NAME + " not added to Rics");
-        assertEquals(ACTIVE, firstRic.state(), "Not correct state for ric " + FIRST_RIC_NAME);
+        assertEquals(IDLE, firstRic.state(), "Not correct state for ric " + FIRST_RIC_NAME);
         assertEquals(1, firstRic.getSupportedPolicyTypes().size(),
             "Not correct no of types supported for ric " + FIRST_RIC_NAME);
         assertTrue(firstRic.isSupportingType(POLICY_TYPE_1_NAME),
@@ -125,7 +127,7 @@ public class StartupServiceTest {
         Ric secondRic = rics.get(SECOND_RIC_NAME);
         assertNotNull(secondRic, "Ric " + SECOND_RIC_NAME + " not added to repository");
         assertEquals(SECOND_RIC_NAME, secondRic.name(), SECOND_RIC_NAME + " not added to Rics");
-        assertEquals(ACTIVE, secondRic.state(), "Not correct state for " + SECOND_RIC_NAME);
+        assertEquals(IDLE, secondRic.state(), "Not correct state for " + SECOND_RIC_NAME);
         assertEquals(2, secondRic.getSupportedPolicyTypes().size(),
             "Not correct no of types supported for ric " + SECOND_RIC_NAME);
         assertTrue(secondRic.isSupportingType(POLICY_TYPE_1_NAME),
@@ -140,11 +142,6 @@ public class StartupServiceTest {
 
     @Test
     public void startup_unableToConnectToGetTypes() {
-        Vector<RicConfig> ricConfigs = new Vector<>(2);
-        ricConfigs.add(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A));
-        ricConfigs.add(getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C));
-        when(appConfigMock.getRicConfigs()).thenReturn(ricConfigs);
-
         Mono<Collection<String>> policyIdentities = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME));
         Mono<?> error = Mono.error(new Exception("Unable to contact ric."));
         doReturn(error, policyIdentities).when(a1ClientMock).getPolicyTypeIdentities(anyString());
@@ -157,24 +154,25 @@ public class StartupServiceTest {
         Rics rics = new Rics();
         PolicyTypes policyTypes = new PolicyTypes();
         StartupService serviceUnderTest =
-            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies());
+            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services());
 
         serviceUnderTest.startup();
+        serviceUnderTest.onRicConfigUpdate(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A),
+            ApplicationConfig.RicConfigUpdate.ADDED);
+        serviceUnderTest.onRicConfigUpdate(
+            getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C),
+            ApplicationConfig.RicConfigUpdate.ADDED);
 
         verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_1);
         verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_2);
 
-        assertEquals(NOT_REACHABLE, rics.get(FIRST_RIC_NAME).state(), "Not correct state for " + FIRST_RIC_NAME);
+        assertEquals(RicState.UNDEFINED, rics.get(FIRST_RIC_NAME).state(), "Not correct state for " + FIRST_RIC_NAME);
 
-        assertEquals(ACTIVE, rics.get(SECOND_RIC_NAME).state(), "Not correct state for " + SECOND_RIC_NAME);
+        assertEquals(IDLE, rics.get(SECOND_RIC_NAME).state(), "Not correct state for " + SECOND_RIC_NAME);
     }
 
     @Test
     public void startup_unableToConnectToGetPolicies() {
-        Vector<RicConfig> ricConfigs = new Vector<>(2);
-        ricConfigs.add(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A));
-        ricConfigs.add(getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C));
-        when(appConfigMock.getRicConfigs()).thenReturn(ricConfigs);
 
         Mono<Collection<String>> policyTypes1 = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME));
         Mono<Collection<String>> policyTypes2 = Mono.just(Arrays.asList(POLICY_TYPE_1_NAME, POLICY_TYPE_2_NAME));
@@ -188,16 +186,21 @@ public class StartupServiceTest {
         Rics rics = new Rics();
         PolicyTypes policyTypes = new PolicyTypes();
         StartupService serviceUnderTest =
-            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies());
+            new StartupService(appConfigMock, rics, policyTypes, a1ClientMock, new Policies(), new Services());
 
         serviceUnderTest.startup();
+        serviceUnderTest.onRicConfigUpdate(getRicConfig(FIRST_RIC_NAME, FIRST_RIC_URL, MANAGED_NODE_A),
+            ApplicationConfig.RicConfigUpdate.ADDED);
+        serviceUnderTest.onRicConfigUpdate(
+            getRicConfig(SECOND_RIC_NAME, SECOND_RIC_URL, MANAGED_NODE_B, MANAGED_NODE_C),
+            ApplicationConfig.RicConfigUpdate.ADDED);
 
         verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_1);
         verify(a1ClientMock).deletePolicy(SECOND_RIC_URL, POLICY_ID_2);
 
-        assertEquals(NOT_REACHABLE, rics.get(FIRST_RIC_NAME).state(), "Not correct state for " + FIRST_RIC_NAME);
+        assertEquals(RicState.UNDEFINED, rics.get(FIRST_RIC_NAME).state(), "Not correct state for " + FIRST_RIC_NAME);
 
-        assertEquals(ACTIVE, rics.get(SECOND_RIC_NAME).state(), "Not correct state for " + SECOND_RIC_NAME);
+        assertEquals(IDLE, rics.get(SECOND_RIC_NAME).state(), "Not correct state for " + SECOND_RIC_NAME);
     }
 
     @SafeVarargs
diff --git a/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java b/policy-agent/src/test/java/org/oransc/policyagent/utils/MockA1Client.java
new file mode 100644 (file)
index 0000000..aca29f5
--- /dev/null
@@ -0,0 +1,96 @@
+/*-
+ * ========================LICENSE_START=================================
+ * O-RAN-SC
+ * %%
+ * Copyright (C) 2019 Nordix Foundation
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.policyagent.utils;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import org.oransc.policyagent.clients.A1Client;
+import org.oransc.policyagent.repository.Policies;
+import org.oransc.policyagent.repository.Policy;
+import org.oransc.policyagent.repository.PolicyType;
+import org.oransc.policyagent.repository.PolicyTypes;
+import reactor.core.publisher.Mono;
+
+public class MockA1Client implements A1Client {
+    private final Map<String, Policies> policies = new HashMap<>();
+    private final PolicyTypes policyTypes;
+
+    public MockA1Client(PolicyTypes policyTypes) {
+        this.policyTypes = policyTypes;
+    }
+
+    @Override
+    public Mono<Collection<String>> getPolicyTypeIdentities(String nearRtRicUrl) {
+        synchronized (this.policyTypes) {
+            Vector<String> result = new Vector<>();
+            for (PolicyType p : this.policyTypes.getAll()) {
+                result.add(p.name());
+            }
+            return Mono.just(result);
+        }
+    }
+
+    @Override
+    public Mono<Collection<String>> getPolicyIdentities(String nearRtRicUrl) {
+        synchronized (this.policies) {
+            Vector<String> result = new Vector<>();
+            for (Policy policy : getPolicies(nearRtRicUrl).getAll()) {
+                if (policy.ric().getConfig().baseUrl().equals(nearRtRicUrl)) {
+                    result.add(policy.id());
+                }
+            }
+
+            return Mono.just(result);
+        }
+    }
+
+    @Override
+    public Mono<String> getPolicyType(String nearRtRicUrl, String policyTypeId) {
+        try {
+            return Mono.just(this.policyTypes.getType(policyTypeId).schema());
+        } catch (Exception e) {
+            return Mono.error(e);
+        }
+    }
+
+    @Override
+    public Mono<String> putPolicy(Policy p) {
+        getPolicies(p.ric().getConfig().baseUrl()).put(p);
+        return Mono.just("OK");
+    }
+
+    @Override
+    public Mono<String> deletePolicy(String nearRtRicUrl, String policyId) {
+        getPolicies(nearRtRicUrl).removeId(policyId);
+        return Mono.just("OK");
+    }
+
+    private Policies getPolicies(String url) {
+        if (!policies.containsKey(url)) {
+            policies.put(url, new Policies());
+        }
+        return policies.get(url);
+    }
+
+}
index fa7410f..02bc864 100644 (file)
@@ -1,42 +1,71 @@
 {
   "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "Example_QoSTarget_1.0.0",
-  "description": "Example QoS Target policy type",
+  "title": "STD_PolicyModelUnconstrained_0.2.0",
+  "description": "Standard model of a policy with unconstrained scope id combinations",
   "type": "object",
   "properties": {
     "scope": {
       "type": "object",
       "properties": {
-        "qosId": {
-          "type": "string"
-        },
-        "cellId": {
-          "type": "string"
-        }
+        "ueId": {"type": "string"},
+        "groupId": {"type": "string"},
+        "sliceId": {"type": "string"},
+        "qosId": {"type": "string"},
+        "cellId": {"type": "string"}
       },
-      "additionalProperties": false,
-      "required": [
-        "qosId"
-      ]
+      "minProperties": 1,
+      "additionalProperties": false
     },
-    "statement": {
+    "qosObjectives": {
       "type": "object",
       "properties": {
-        "gfbr": {
-          "type": "number"
-        },
-        "mfbr": {
-          "type": "number"
-        },
-        "priorityLevel": {
-          "type": "number"
-        },
-        "pdb": {
-          "type": "number"
-        }
+        "gfbr": {"type": "number"},
+        "mfbr": {"type": "number"},
+        "priorityLevel": {"type": "number"},
+        "pdb": {"type": "number"}
       },
-      "minProperties": 1,
       "additionalProperties": false
+    },
+    "qoeObjectives": {
+      "type": "object",
+      "properties": {
+        "qoeScore": {"type": "number"},
+        "initialBuffering": {"type": "number"},
+        "reBuffFreq": {"type": "number"},
+        "stallRatio": {"type": "number"}
+      },
+      "additionalProperties": false
+    },
+    "resources": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "properties": {
+          "cellIdList": {
+            "type": "array",
+            "minItems": 1,
+            "uniqueItems": true,
+            "items": {
+              "type": "string"
+            }
+          },
+          "preference": {
+            "type": "string",
+            "enum": [
+              "SHALL",
+              "PREFER",
+              "AVOID",
+              "FORBID"
+            ]
+          },
+          "primary": {"type": "boolean"}
+        },
+        "additionalProperties": false,
+        "required": ["cellIdList", "preference"]
+      }
     }
-  }
-}
\ No newline at end of file
+  },
+  "minProperties": 2,
+  "additionalProperties": false,
+  "required": ["scope"]
+}
index 695514c..a73dd59 100644 (file)
@@ -1,59 +1,27 @@
 {
   "$schema": "http://json-schema.org/draft-07/schema#",
-  "title": "Example_TrafficSteeringPreference_1.0.0",
-  "description": "Example QoE Target policy type",
+  "title": "ERIC_QoSNudging_0.2.0",
+  "description": "QoS nudging policy type with priorityLevel and ueId and qosId as scope",
   "type": "object",
   "properties": {
     "scope": {
       "type": "object",
       "properties": {
-        "ueId": {
-          "type": "string"
-        },
-        "sliceId": {
-          "type": "string"
-        },
-        "qosId": {
-          "type": "string"
-        },
-        "cellId": {
-          "type": "string"
-        }
+        "ueId": {"type": "string"},
+        "qosId": {"type": "string"}
       },
       "additionalProperties": false,
-      "required": [
-        "ueId"
-      ]
+      "required": ["ueId", "qosId"]
     },
-    "statement": {
+    "qosObjectives": {
       "type": "object",
       "properties": {
-        "cellIdList": {
-          "type": "array",
-          "minItems": 1,
-          "uniqueItems": true,
-          "items": {
-            "type": "string"
-          }
-        },
-        "preference": {
-          "type": "string",
-          "enum": [
-            "SHALL",
-            "PREFER",
-            "AVOID",
-            "FORBID"
-          ]
-        },
-        "primary": {
-          "type": "boolean"
-        }
+        "priorityLevel": {"type": "number"}
       },
-      "required": [
-        "cellIdList",
-        "preference"
-      ],
-      "additionalProperties": false
+      "additionalProperties": false,
+      "required": ["priorityLevel"]
     }
-  }
-}
\ No newline at end of file
+  },
+  "additionalProperties": false,
+  "required": ["scope", "qosObjectives"]
+}
index 7033c4a..924b1dd 100644 (file)
@@ -9,7 +9,15 @@
                "kista_1",
                "kista_2"
             ]
+         },
+         {
+            "name": "ric2",
+            "baseUrl": "http://localhost:8081/",
+            "managedElementIds": [
+               "kista_3",
+               "kista_4"
+            ]
          }
       ]
    }
-}
\ No newline at end of file
+}