.tox
docs/_build/
.DS_STORE
+
+# Eclipse
+.checkstyle
+.sts4-cache
\ No newline at end of file
<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>
<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>
<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>
* 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.
@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";
+ }
}
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";
}
* 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;
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);
+ }
}
@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);
+ }
}
* 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.
@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;
+ }
}
@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;
+ }
}
@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();
+ }
}
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;
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
@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;
+ }
}
* 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.
/**
* 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
@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);
+ }
+ }
}
* 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.
@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());
+ }
}
*/
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;
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.
@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);
+ }
+}
* 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.
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;
/**
* 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
*/
@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";
+ }
}
*/
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();
+ }
}
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();
+ }
}
* 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.
*/
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;
+ }
}
@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();
}
public class PolicyInstances extends ArrayList<PolicyInfo> {
- private static final long serialVersionUID = -928428052502491021L;
+ private static final long serialVersionUID = -928428052502491021L;
}
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 + "]";
+ }
}
public class PolicyTypes extends ArrayList<PolicyType> {
- private static final long serialVersionUID = -928428052502491021L;
+ private static final long serialVersionUID = -928428052502491021L;
}
* 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.
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;
+ }
}
* 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);
}
* 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 {
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;
}
}
@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
}
@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;
}
}
* 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.
*/
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;
}
* 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.
*/
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;
+ }
}
* 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.
* 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();
+ }
}
* 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.
* 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);
+ }
}
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);
+ }
}
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);
+ }
}
* 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.
* 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.");
+ }
}
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;
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;
/**
@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);
+ }
}
*/
package org.oransc.ric.portal.dashboard.config;
+import com.google.gson.GsonBuilder;
+
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
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;
/**
@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<>();
+
+ }
}
@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;
+ }
}
@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
+ }
}
* 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.
@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);
+ }
}
@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");
+ }
}
* 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.
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());
+ * }
+ */
}
import java.util.Collection;
+import org.oransc.policyagent.repository.Policy;
import reactor.core.publisher.Mono;
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);
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;
return nearRtRicUrl + "/A1-P/v1";
}
- public AsyncRestClient createClient(final String nearRtRicUrl) {
+ protected AsyncRestClient createClient(final String nearRtRicUrl) {
return new AsyncRestClient(getBaseUrl(nearRtRicUrl));
}
}
@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);
}
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;
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);
public void initialize() {
stop();
- loadConfigurationFromFile(this.filepath);
+ loadConfigurationFromFile();
refreshConfigTask = createRefreshTask() //
.subscribe(notUsed -> logger.info("Refreshed configuration data"),
() -> 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);
}
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() {
/**
* 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);
}
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);
+++ /dev/null
-/*-
- * ========================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
-
- }
-
-}
@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);
+ }
}
}
}
@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);
+ }
}
}
}
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 -> {
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) //
.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));
@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) {
})
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());
+ }
}
}
}
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);
}
public long keepAliveInterval();
+ public String callbackUrl();
+
}
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;
if (map == null) {
return new Vector<Policy>();
}
- return map.values();
+ return Collections.unmodifiableCollection(map.values());
}
public synchronized boolean containsPolicy(String id) {
}
public synchronized Collection<Policy> getAll() {
- return policiesId.values();
+ return Collections.unmodifiableCollection(policiesId.values());
}
public synchronized Collection<Policy> getForService(String service) {
package org.oransc.policyagent.repository;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
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();
}
}
*/
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<>();
/**
*/
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
}
}
package org.oransc.policyagent.repository;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
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);
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();
}
}
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();
}
return Duration.between(this.lastPing, Instant.now());
}
+ public synchronized String getCallbackUrl() {
+ return this.callbackUrl;
+ }
+
}
package org.oransc.policyagent.repository;
-import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
services.put(service.getName(), service);
}
- public synchronized Collection<Service> getAll() {
+ public synchronized Iterable<Service> getAll() {
return services.values();
}
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;
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;
}
/**
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)) {
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();
}
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();
}
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;
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;
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);
+ }
}
}
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)); //
}
}
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()) //
}
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) {
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);
@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);
+ }
+ }
}
/**
*/
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
}
}
import com.google.gson.reflect.TypeToken;
import java.net.URL;
-import java.util.Collection;
import java.util.List;
import java.util.Vector;
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;
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)
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();
}
}
@Bean
A1Client getA1Client() {
- return new A1ClientMock(this.policies, this.policyTypes);
+ return new MockA1Client(this.policyTypes);
}
@Bean
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);
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);
ServiceRegistrationInfo service = ImmutableServiceRegistrationInfo.builder() //
.keepAliveInterval(1) //
.name(name) //
+ .callbackUrl("callbackUrl") //
.build();
String json = gson.toJson(service);
return json;
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;
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) {
}
}
}
- }
- /**
- * 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
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;
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;
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;
@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());
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);
}
// 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
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)
.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") //
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);
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");
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;
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)
@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);
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);
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),
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),
@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());
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));
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
--- /dev/null
+/*-
+ * ========================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);
+ }
+
+}
{
"$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"]
+}
{
"$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"]
+}
"kista_1",
"kista_2"
]
+ },
+ {
+ "name": "ric2",
+ "baseUrl": "http://localhost:8081/",
+ "managedElementIds": [
+ "kista_3",
+ "kista_4"
+ ]
}
]
}
-}
\ No newline at end of file
+}