</dependency>
</dependencies>
<build>
+ <!-- Ensure property files used for testing are NEVER packaged -->
+ <resources>
+ <resource>
+ <directory>src/main/resources</directory>
+ <excludes>
+ <exclude>key.properties</exclude>
+ <exclude>portal.properties</exclude>
+ </excludes>
+ <filtering>false</filtering>
+ </resource>
+ </resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
-import java.util.ListIterator;
-import javax.servlet.http.HttpServletResponse;
-
-import org.onap.portalsdk.core.onboarding.exception.PortalAPIException;
-import org.onap.portalsdk.core.restful.domain.EcompUser;
-import org.oransc.ric.portal.dashboard.model.StatsDetailsTransport;
import org.oransc.ric.portal.dashboard.exception.StatsManagerException;
-import org.oransc.ric.portal.dashboard.model.IDashboardResponse;
import org.oransc.ric.portal.dashboard.model.AppStats;
+import org.oransc.ric.portal.dashboard.model.StatsDetailsTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
-import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* Development/test-only constructor that uses default file path.
*
- * @param clear If true, start empty and remove any existing file.
+ * @param clear
+ * If true, start empty and remove any existing file.
*
- * @throws IOException On file error
+ * @throws IOException
+ * On file error
*/
public AppStatsManager(boolean clear) throws IOException {
this(STATS_FILE_PATH);
/**
* Constructor that accepts a file path
*
- * @param statsFilePath File path
- * @throws IOException If file cannot be read
+ * @param statsFilePath
+ * File path
+ * @throws IOException
+ * If file cannot be read
*/
public AppStatsManager(final String statsFilePath) throws IOException {
logger.debug("ctor: statsfile {}", statsFilePath);
final ObjectMapper mapper = new ObjectMapper();
stats = mapper.readValue(statsFile, new TypeReference<List<AppStats>>() {
});
- for (AppStats st: stats) {
- if (st.getStatsDetails().getAppId()>appMaxId)
+ for (AppStats st : stats) {
+ if (st.getStatsDetails().getAppId() > appMaxId)
appMaxId = st.getStatsDetails().getAppId();
}
} else {
/**
* Gets the current app metric stats by instance key.
*
- * @param instanceKey Desired instance key
+ * @param instanceKey
+ * Desired instance key
* @return List of App stat objects by instance key, possibly empty
*/
public List<AppStats> getStatsByInstance(String instanceKey) {
/**
* Gets the stats with the specified app Id and instance key
*
- * @param appId Desired app Id
- * @param instanceKey Desired instance key
+ * @param appId
+ * Desired app Id
+ * @param instanceKey
+ * Desired instance key
* @return Stats object; null if Id is not known
*/
public AppStats getStatsById(String instanceKey, int appId) {
}
/*
- * Allow at most one thread to create a stats at one time.
- * Before creating new stat, checks for composite key (appname,url) uniqueness for an instance key
+ * Allow at most one thread to create a stats at one time. Before creating new
+ * stat, checks for composite key (appname,url) uniqueness for an instance key
*/
public synchronized AppStats createStats(String instanceKey, StatsDetailsTransport statsSetupRequest)
throws StatsManagerException, IOException {
if (st.getInstanceKey().equals(instanceKey)
&& st.getStatsDetails().getAppName().equals(statsSetupRequest.getAppName())
&& st.getStatsDetails().getMetricUrl().equals(statsSetupRequest.getMetricUrl())) {
- String msg = "App exists with name " + statsSetupRequest.getAppName() + " and url "+statsSetupRequest.getMetricUrl()+ " on instance key " + instanceKey;
+ String msg = "App exists with name " + statsSetupRequest.getAppName() + " and url "
+ + statsSetupRequest.getMetricUrl() + " on instance key " + instanceKey;
logger.warn(msg);
throw new StatsManagerException(msg);
}
}
AppStats newAppStat = null;
- //Assigns appId to be 1 more than the largest value stored in memory
- appMaxId = appMaxId+1;
+ // Assigns appId to be 1 more than the largest value stored in memory
+ appMaxId = appMaxId + 1;
newAppStat = new AppStats(instanceKey,
new StatsDetailsTransport(appMaxId, statsSetupRequest.getAppName(), statsSetupRequest.getMetricUrl()));
stats.add(newAppStat);
logger.debug("ctor statsfile '{}'", statsfile);
this.userfile = userfile;
this.statsfile = statsfile;
-
}
@Bean
private final RicRegionList instanceConfig;
@Autowired
- public CaasIngressConfiguration( //
- @Value("${caasingress.plt.url.suffix}") final String pltUrlSuffix, //
+ public CaasIngressConfiguration(@Value("${caasingress.plt.url.suffix}") final String pltUrlSuffix, //
@Value("${caasingress.insecure}") final Boolean insecureFlag, //
final RicRegionList instanceConfig) throws KeyManagementException, NoSuchAlgorithmException {
logger.debug("ctor: suffix {} insecure flag {}", pltUrlSuffix, insecureFlag);
@Autowired
public E2ManagerConfiguration(@Value("${e2mgr.url.suffix}") final String urlSuffix,
final RicRegionList instanceConfig) {
- logger.info("ctor: URL suffix {}", urlSuffix);
+ logger.debug("ctor: URL suffix {}", urlSuffix);
this.urlSuffix = urlSuffix;
this.instanceConfig = instanceConfig;
}
import java.io.IOException;
import java.lang.invoke.MethodHandles;
-import java.util.ArrayList;
import java.util.List;
import org.onap.portalsdk.core.restful.domain.EcompUser;
+import org.oransc.ric.portal.dashboard.AppStatsManager;
import org.oransc.ric.portal.dashboard.DashboardApplication;
import org.oransc.ric.portal.dashboard.DashboardConstants;
import org.oransc.ric.portal.dashboard.DashboardUserManager;
-import org.oransc.ric.portal.dashboard.AppStatsManager;
import org.oransc.ric.portal.dashboard.exception.StatsManagerException;
+import org.oransc.ric.portal.dashboard.model.AppStats;
import org.oransc.ric.portal.dashboard.model.IDashboardResponse;
-import org.oransc.ric.portal.dashboard.model.StatsDetailsTransport;
import org.oransc.ric.portal.dashboard.model.RicRegion;
import org.oransc.ric.portal.dashboard.model.RicRegionList;
import org.oransc.ric.portal.dashboard.model.RicRegionTransport;
-import org.oransc.ric.portal.dashboard.model.AppStats;
+import org.oransc.ric.portal.dashboard.model.StatsDetailsTransport;
import org.oransc.ric.portal.dashboard.model.SuccessTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-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.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.ApiOperation;
ex.toString());
return ResponseEntity.badRequest().body(getShortExceptionMessage(ex));
}
-
+
/**
* Logs a warning if a StatsManagerException is thrown.
*
*/
@ExceptionHandler({ StatsManagerException.class })
public final ResponseEntity<String> handleStatsManagerException(Exception ex, WebRequest request) {
- log.warn("handleStatsManagerException: request {}, exception {}", request.getDescription(false),
- ex.toString());
+ log.warn("handleStatsManagerException: request {}, exception {}", request.getDescription(false), ex.toString());
return ResponseEntity.badRequest().body(getShortExceptionMessage(ex));
}
server:
port: 8080
-# path to file that stores user details;
+# paths to files that store details;
# use a persistent volume in a K8S deployment
userfile: users.json
+statsfile: stats.json
# Dashboard properties related to Portal
portalapi:
package org.oransc.ric.portal.dashboard.config;
import java.io.IOException;
-import java.io.PrintWriter;
import java.lang.invoke.MethodHandles;
-import java.util.Collection;
import java.util.HashSet;
-import java.util.Locale;
import java.util.Set;
import org.onap.portalsdk.core.onboarding.exception.PortalAPIException;
import org.onap.portalsdk.core.restful.domain.EcompRole;
import org.onap.portalsdk.core.restful.domain.EcompUser;
-import org.oransc.ric.portal.dashboard.DashboardUserManager;
import org.oransc.ric.portal.dashboard.AppStatsManager;
+import org.oransc.ric.portal.dashboard.DashboardUserManager;
import org.oransc.ric.portal.dashboard.exception.StatsManagerException;
-import org.oransc.ric.portal.dashboard.model.AppStats;
import org.oransc.ric.portal.dashboard.model.StatsDetailsTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-
/**
* Creates user manager and stats manager with mock data.
*/
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
+ // Autowire all the properties required by the real class
+ // (even tho not used here) as a test of the properties.
@Autowired
- public AdminMockConfiguration() {
+ public AdminMockConfiguration(@Value("${userfile}") final String userfile,
+ @Value("${statsfile}") final String statsfile) {
+ logger.info("ctor userfile {} statsfile {}", userfile, statsfile);
}
@Bean
import java.lang.invoke.MethodHandles;
+import org.oransc.ric.portal.dashboard.model.RicRegionList;
import org.oransc.ricplt.appmgr.client.api.HealthApi;
import org.oransc.ricplt.appmgr.client.api.XappApi;
import org.oransc.ricplt.appmgr.client.invoker.ApiClient;
// Simulate remote method delay for UI testing
private int delayMs;
+ // Autowire all the properties required by the real class
+ // (even tho not used here) as a test of the properties.
@Autowired
- public AppManagerMockConfiguration(@Value("${mock.config.delay:0}") int delayMs) {
- logger.debug("ctor: configured with delay {}", delayMs);
+ public AppManagerMockConfiguration(@Value("${appmgr.url.suffix}") final String urlSuffix, //
+ final RicRegionList instanceConfig, //
+ @Value("${mock.config.delay:0}") int delayMs) {
+ logger.info("ctor: configured with suffix {}, instances {}, delay {}", urlSuffix, instanceConfig, delayMs);
this.delayMs = delayMs;
}
import org.oransc.ric.portal.dashboard.TestUtils;
import org.oransc.ric.portal.dashboard.k8sapi.SimpleKubernetesClient;
+import org.oransc.ric.portal.dashboard.model.RicRegionList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
// Simulate remote method delay for UI testing
private int delayMs;
+ // Autowire all the properties required by the real class
+ // (even tho not used here) as a test of the properties.
@Autowired
- public CaasIngressMockConfiguration(@Value("${mock.config.delay:0}") int delayMs) {
- logger.debug("ctor: configured with delay {}", delayMs);
+ public CaasIngressMockConfiguration(@Value("${caasingress.plt.url.suffix}") final String pltUrlSuffix, //
+ @Value("${caasingress.insecure}") final Boolean insecureFlag, //
+ final RicRegionList instanceConfig, //
+ @Value("${mock.config.delay:0}") int delayMs) {
+ logger.info("ctor: configured with suffix {}, insecure {}, instance {}, delay {}", pltUrlSuffix, insecureFlag,
+ instanceConfig, delayMs);
this.delayMs = delayMs;
}
import java.util.List;
import java.util.Map;
+import org.oransc.ric.portal.dashboard.model.RicRegionList;
import org.oransc.ricplt.e2mgr.client.api.HealthCheckApi;
import org.oransc.ricplt.e2mgr.client.api.NodebApi;
import org.oransc.ricplt.e2mgr.client.invoker.ApiClient;
// Simulate remote method delay for UI testing
private int delayMs;
+ // Autowire all the properties required by the real class
+ // (even tho not used here) as a test of the properties.
@Autowired
- public E2ManagerMockConfiguration(@Value("${mock.config.delay:0}") int delayMs) {
- logger.debug("ctor: configured with delay {}", delayMs);
+ public E2ManagerMockConfiguration(@Value("${e2mgr.url.suffix}") final String urlSuffix, //
+ final RicRegionList instanceConfig, //
+ @Value("${mock.config.delay:0}") int delayMs) {
+ logger.info("ctor: configured with suffix {}, instances {}, delay {}", urlSuffix, instanceConfig, delayMs);
this.delayMs = delayMs;
}
// "globalNbId":null,"gnb":null,"ip":"10.2.0.6","nodeType":null,"port":36444,
// "ranName":"AAAA123456","setupFailure":null}}]
nodebIdList.add(new NodebIdentity().inventoryName(RAN_NAME_1).globalNbId(globalNbId));
- nodebResponseMap.put(RAN_NAME_1,
- new GetNodebResponse().connectionStatus("CONNECTING").ip("127.0.0.1").port(456).ranName(RAN_NAME_2).nodeType("ENDC").port(100));
+ nodebResponseMap.put(RAN_NAME_1, new GetNodebResponse().connectionStatus("CONNECTING").ip("127.0.0.1").port(456)
+ .ranName(RAN_NAME_2).nodeType("ENDC").port(100));
nodebIdList.add(new NodebIdentity().inventoryName(RAN_NAME_2).globalNbId(globalNbId));
- nodebResponseMap.put(RAN_NAME_2,
- new GetNodebResponse().connectionStatus("CONNECTED").ip("127.0.0.2").port(456).ranName(RAN_NAME_2).nodeType("X2").port(200));
+ nodebResponseMap.put(RAN_NAME_2, new GetNodebResponse().connectionStatus("CONNECTED").ip("127.0.0.2").port(456)
+ .ranName(RAN_NAME_2).nodeType("X2").port(200));
ApiClient apiClient = apiClient();
NodebApi mockApi = mock(NodebApi.class);
// 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;
- @Value("${userfile}")
- private String userFilePath;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
# ========================LICENSE_END===================================
# Test properties for the EPSDK-FW library.
-# This file must be present on the Java classpath.
+# This file must be present on the Java classpath to test.
+# This file must not be packaged into the jar!
cipher.enc.key = bogus
# ========================LICENSE_END===================================
# Test properties for the EPSDK-FW library.
-# This file must be present on the Java classpath.
+# This file must be present on the Java classpath to test.
+# This file must not be packaged into the jar!
portal.api.impl.class = org.oransc.ric.portal.dashboard.portalapi.PortalRestCentralServiceImpl
role_access_centralized = remote
RIC Dashboard Release Notes
===========================
-Version 2.0.1, 8 Apr 2020
+Version 2.0.1, 15 Apr 2020
--------------------------
* update and relocate the theme selector button
* Revise controllers to use ResponseEntity
* Upgrade to Spring-Boot 2.2.4.RELEASE
* Set the first instance as the default one
* Add methods to create, update and delete xApp stat metric URLs
+* Rearrange property files to support testing default context
Version 2.0.0, 5 Feb 2020
--------------------------