aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--aai-resources/pom.xml9
-rw-r--r--aai-resources/src/main/java/org/onap/aai/ResourcesApp.java13
-rw-r--r--aai-resources/src/main/java/org/onap/aai/rest/util/EchoResponse.java200
-rw-r--r--aai-resources/src/main/java/org/onap/aai/tasks/AaiGraphChecker.java208
-rw-r--r--aai-resources/src/main/resources/etc/appprops/aaiconfig.properties15
-rw-r--r--aai-resources/src/main/resources/localhost-access-logback.xml16
-rw-r--r--aai-resources/src/main/resources/logback.xml108
-rw-r--r--aai-resources/src/test/java/org/onap/aai/AAISetup.java3
-rw-r--r--aai-resources/src/test/java/org/onap/aai/rest/util/EchoResponseTest.java152
-rw-r--r--aai-resources/src/test/java/org/onap/aai/task/AaiGraphCheckerTest.java70
-rw-r--r--aai-resources/src/test/resources/etc/appprops/aaiconfig.properties13
11 files changed, 638 insertions, 169 deletions
diff --git a/aai-resources/pom.xml b/aai-resources/pom.xml
index e7e81e7..364dc57 100644
--- a/aai-resources/pom.xml
+++ b/aai-resources/pom.xml
@@ -428,6 +428,15 @@
<artifactId>logback-access</artifactId>
</dependency>
<dependency>
+ <groupId>org.codehaus.janino</groupId>
+ <artifactId>janino</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.logstash.logback</groupId>
+ <artifactId>logstash-logback-encoder</artifactId>
+ <version>6.6</version>
+ </dependency>
+ <dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-junit</artifactId>
</dependency>
diff --git a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
index 6377af8..419fee5 100644
--- a/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
+++ b/aai-resources/src/main/java/org/onap/aai/ResourcesApp.java
@@ -1,4 +1,4 @@
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
@@ -17,8 +17,11 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.onap.aai;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.onap.aai.aailog.logs.AaiDebugLog;
import org.onap.aai.config.SpringContextAware;
@@ -32,7 +35,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
@@ -40,9 +42,6 @@ import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfigurat
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
-import javax.annotation.PostConstruct;
-import javax.annotation.PreDestroy;
-
@SpringBootApplication(
exclude = {
DataSourceAutoConfiguration.class,
@@ -87,8 +86,8 @@ public class ResourcesApp {
@Autowired
private SpringContextAware loaderFactory;
-
-
+
+
@PostConstruct
private void init() throws AAIException {
System.setProperty("org.onap.aai.serverStarted", "false");
diff --git a/aai-resources/src/main/java/org/onap/aai/rest/util/EchoResponse.java b/aai-resources/src/main/java/org/onap/aai/rest/util/EchoResponse.java
index b72d113..8b5eef6 100644
--- a/aai-resources/src/main/java/org/onap/aai/rest/util/EchoResponse.java
+++ b/aai-resources/src/main/java/org/onap/aai/rest/util/EchoResponse.java
@@ -1,4 +1,4 @@
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
@@ -8,7 +8,7 @@
* 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
+ * 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,
@@ -17,12 +17,11 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.rest.util;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.restcore.RESTAPI;
+package org.onap.aai.rest.util;
+import java.util.ArrayList;
+import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@@ -33,88 +32,123 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
-import java.util.ArrayList;
-import java.util.HashMap;
+import org.apache.commons.lang3.BooleanUtils;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.restcore.RESTAPI;
+import org.onap.aai.tasks.AaiGraphChecker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
/**
* The Class EchoResponse.
*/
+@Component
@Path("/util")
public class EchoResponse extends RESTAPI {
-
- protected static String authPolicyFunctionName = "util";
-
- public static final String echoPath = "/util/echo";
-
- /**
- * Simple health-check API that echos back the X-FromAppId and X-TransactionId to clients.
- * If there is a query string, a transaction gets logged into hbase, proving the application is connected to the data store.
- * If there is no query string, no transacction logging is done to hbase.
- *
- * @param headers the headers
- * @param req the req
- * @param myAction if exists will cause transaction to be logged to hbase
- * @return the response
- */
- @GET
- @Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- @Path("/echo")
- public Response echoResult(@Context HttpHeaders headers, @Context HttpServletRequest req,
- @QueryParam("action") String myAction) {
- Response response = null;
-
- AAIException ex = null;
- String fromAppId = null;
- String transId = null;
-
- try {
- fromAppId = getFromAppId(headers );
- transId = getTransId(headers);
- } catch (AAIException e) {
- ArrayList<String> templateVars = new ArrayList<String>();
- templateVars.add("PUT uebProvider");
- templateVars.add("addTopic");
- return Response
- .status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
- .build();
- }
-
- try {
-
- HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<AAIException, ArrayList<String>>();
-
- ArrayList<String> templateVars = new ArrayList<String>();
- templateVars.add(fromAppId);
- templateVars.add(transId);
-
- exceptionList.put(new AAIException("AAI_0002", "OK"), templateVars);
-
- response = Response.status(Status.OK)
- .entity(ErrorLogHelper.getRESTAPIInfoResponse(
- headers.getAcceptableMediaTypes(), exceptionList))
- .build();
-
- } catch (Exception e) {
- ex = new AAIException("AAI_4000", e);
- ArrayList<String> templateVars = new ArrayList<String>();
- templateVars.add(Action.GET.name());
- templateVars.add(fromAppId +" "+transId);
-
- response = Response
- .status(Status.INTERNAL_SERVER_ERROR)
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(
- headers.getAcceptableMediaTypes(), ex,
- templateVars)).build();
-
- } finally {
- if (ex != null) {
- ErrorLogHelper.logException(ex);
- }
-
- }
-
- return response;
- }
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(EchoResponse.class);
+
+ private static final String CHECK_DB_STATUS_ACTION = "checkDB";
+
+ private static final String CHECK_DB_STATUS_NOW_ACTION = "checkDBNow";
+
+ private final AaiGraphChecker aaiGraphChecker;
+
+ public EchoResponse(AaiGraphChecker aaiGraphChecker) {
+ this.aaiGraphChecker = aaiGraphChecker;
+ }
+
+ /**
+ * Simple health-check API that echos back the X-FromAppId and X-TransactionId to clients.
+ * If there is a query string, a transaction gets logged into hbase, proving the application is connected to the
+ * data store.
+ * If there is no query string, no transacction logging is done to hbase.
+ *
+ * @param headers the headers
+ * @param req the req
+ * @param myAction if exists will cause transaction to be logged to hbase
+ * @return the response
+ */
+ @GET
+ @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
+ @Path("/echo")
+ public Response echoResult(
+ @Context HttpHeaders headers, @Context HttpServletRequest req, @QueryParam("action") String myAction) {
+
+ String fromAppId;
+ String transId;
+ try {
+ fromAppId = getFromAppId(headers);
+ transId = getTransId(headers);
+ } catch (AAIException aaiException) {
+ ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add("PUT uebProvider");
+ templateVars.add("addTopic");
+ LOGGER.error("Error while getting ids", aaiException);
+ return generateFailureResponse(headers, templateVars, aaiException);
+ }
+
+ ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add(fromAppId);
+ templateVars.add(transId);
+
+ try {
+ if (CHECK_DB_STATUS_ACTION.equalsIgnoreCase(myAction) ||
+ CHECK_DB_STATUS_NOW_ACTION.equalsIgnoreCase(myAction)) {
+ validateDBStatus(myAction);
+ }
+ return generateSuccessResponse(headers, templateVars);
+
+ } catch (AAIException aaiException) {
+ LOGGER.error("Error while processing echo request ", aaiException);
+ return generateFailureResponse(headers, templateVars, aaiException);
+ } catch (Exception exception) {
+ AAIException aaiException = new AAIException("AAI_4000", exception);
+ LOGGER.error("Error while generating echo response", exception);
+ return generateFailureResponse(headers, templateVars, aaiException);
+ }
+ }
+
+ /**
+ * Validates if Janus Graph can process request using AAIGraphChecker.
+ *
+ * @param action expected input values 'checkDB' 'checkDBNow'
+ * @throws AAIException exception thrown if DB is not available
+ */
+ private void validateDBStatus(String action) throws AAIException {
+
+ Boolean dbAvailable = null;
+ if (CHECK_DB_STATUS_ACTION.equalsIgnoreCase(action)) {
+ dbAvailable = aaiGraphChecker.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.CACHED);
+ } else if (CHECK_DB_STATUS_NOW_ACTION.equalsIgnoreCase(action)) {
+ dbAvailable = aaiGraphChecker.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.ACTUAL);
+ } else {
+ LOGGER.error("Invalid check db action specified to generate echo response: '{}'", action);
+ }
+
+ if (BooleanUtils.isFalse(dbAvailable)) {
+ throw new AAIException("AAI_5105", "Error establishing a database connection");
+ }
+
+ }
+
+ private Response generateSuccessResponse(HttpHeaders headers, ArrayList<String> templateVariables) {
+ HashMap<AAIException, ArrayList<String>> exceptionList = new HashMap<>();
+ exceptionList.put(new AAIException("AAI_0002", "OK"), templateVariables);
+ return Response.status(Status.OK)
+ .entity(
+ ErrorLogHelper.getRESTAPIInfoResponse(headers.getAcceptableMediaTypes(), exceptionList)).build();
+ }
+
+ private Response generateFailureResponse(HttpHeaders headers, ArrayList<String> templateVariables,
+ AAIException aaiException) {
+ return Response.status(aaiException.getErrorObject().getHTTPResponseCode())
+ .entity(
+ ErrorLogHelper.getRESTAPIErrorResponseWithLogging(
+ headers.getAcceptableMediaTypes(), aaiException, templateVariables))
+ .build();
+ }
}
diff --git a/aai-resources/src/main/java/org/onap/aai/tasks/AaiGraphChecker.java b/aai-resources/src/main/java/org/onap/aai/tasks/AaiGraphChecker.java
new file mode 100644
index 0000000..d1ea478
--- /dev/null
+++ b/aai-resources/src/main/java/org/onap/aai/tasks/AaiGraphChecker.java
@@ -0,0 +1,208 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada
+ * ================================================================================
+ * 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.onap.aai.tasks;
+
+import com.google.common.collect.Iterators;
+import java.util.Iterator;
+import java.util.Timer;
+import java.util.TimerTask;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.Validate;
+import org.janusgraph.core.JanusGraphException;
+import org.janusgraph.core.JanusGraphTransaction;
+import org.janusgraph.core.JanusGraphVertex;
+import org.onap.aai.dbmap.AAIGraph;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.util.AAIConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+/**
+ * Singleton class responsible to check that AAI service is able to connect to its back-end database.
+ * The check can run as a scheduled task or on demand.
+ */
+@Component
+@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
+public class AaiGraphChecker extends TimerTask {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AaiGraphChecker.class);
+
+ // Default indicator to enable or disable scheduled task
+ private static final String DEFAULT_SCHEDULE_ENABLED_VALUE = "false";
+ // Default delay, in seconds, before the scheduled task is started, if enabled
+ private static final String DEFAULT_SCHEDULE_DELAY_VALUE = "5";
+ // Default period, in seconds, between two consecutive executions of the scheduled task, if enabled
+ private static final String DEFAULT_SCHEDULE_PERIOD_VALUE = "60";
+
+ // Database availability cached indicator
+ private volatile Boolean isAaiGraphDbAvailableCache = null;
+
+ private Timer timer = null;
+
+ /**
+ * Enumeration of check type that can be made.
+ */
+ public enum CheckerType {
+ ACTUAL,
+ CACHED
+ }
+
+ private AaiGraphChecker() {
+ }
+
+ @PostConstruct
+ private void setupTimer() {
+
+ boolean scheduleEnabled =
+ Boolean.parseBoolean(
+ getConfigurationValueOrDefault(
+ "aai.graph.checker.task.enabled", DEFAULT_SCHEDULE_ENABLED_VALUE));
+ long scheduleDelay =
+ Long.parseLong(
+ getConfigurationValueOrDefault(
+ "aai.graph.checker.task.delay", DEFAULT_SCHEDULE_DELAY_VALUE));
+ long schedulePeriod =
+ Long.parseLong(
+ getConfigurationValueOrDefault(
+ "aai.graph.checker.task.period", DEFAULT_SCHEDULE_PERIOD_VALUE));
+ LOGGER.debug(
+ "Setting up AaiGraphChecker with scheduleEnabled={}, scheduleDelay={}, schedulePeriod={} ",
+ scheduleEnabled, scheduleDelay, schedulePeriod);
+
+ if (scheduleEnabled) {
+ timer = new Timer();
+ timer.schedule(this, scheduleDelay * 1000, schedulePeriod * 1000);
+ }
+ }
+
+ @PreDestroy
+ private void tearDownTimer() {
+ LOGGER.debug("Tear down AaiGraphChecker");
+ if (timer != null) {
+ timer.cancel();
+ timer = null;
+ }
+ }
+
+ @Override
+ public void run() {
+ isAaiGraphDbAvailable(CheckerType.ACTUAL);
+ }
+
+ /**
+ * Clear database availability cached indicator.
+ */
+ public void clearDbAvailabilityCachedIndicator() {
+ isAaiGraphDbAvailableCache = null;
+ }
+
+ /**
+ * Indicate if AAI Graph database is available either from actual db connection or from cached property state.
+ * @param checkerType the type of check to be made (actual or cached). Null is not supported.
+ * @return
+ * <li>true, if database is available</li>
+ * <li>false, if database is NOT available</li>
+ * <li>null, if database availability can not be determined</li>
+ */
+ public Boolean isAaiGraphDbAvailable(CheckerType checkerType) {
+ Validate.notNull(checkerType);
+ if (CheckerType.ACTUAL.equals(checkerType)) {
+ isAaiGraphDbAvailableCache = isAaiGraphDbAvailableActual();
+ }
+ logDbState(checkerType);
+ return isAaiGraphDbAvailableCache;
+ }
+
+ private Boolean isAaiGraphDbAvailableActual() {
+ Boolean dbAvailable;
+ JanusGraphTransaction transaction = null;
+ try {
+ transaction = AAIGraph.getInstance().getGraph().newTransaction();
+ final Iterator<JanusGraphVertex> vertexIterator = transaction.query().limit(1).vertices().iterator();
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Number of vertices retrieved while checking db: {}", Iterators.size(vertexIterator));
+ }
+ vertexIterator.hasNext();
+ LOGGER.debug("Actual database availability is true");
+ dbAvailable = Boolean.TRUE;
+ } catch (JanusGraphException e) {
+ String message = "Actual database availability is false (after JanusGraph exception)";
+ ErrorLogHelper.logError("500", message + ": " + e.getMessage());
+ LOGGER.error(message, e);
+ dbAvailable = Boolean.FALSE;
+ } catch (Error e) {
+ // Following error occurs when aai resources is starting:
+ // - UnsatisfiedLinkError (for org.onap.aai.dbmap.AAIGraph$Helper instantiation)
+ // Following errors are raised when aai resources is starting and cassandra is not running:
+ // - ExceptionInInitializerError
+ // - NoClassDefFoundError (definition for org.onap.aai.dbmap.AAIGraph$Helper is not found)
+ String message = "Actual database availability is false (after error)";
+ ErrorLogHelper.logError("500", message + ": " + e.getMessage());
+ LOGGER.error(message, e);
+ dbAvailable = Boolean.FALSE;
+ } catch (Exception e) {
+ String message = "Actual database availability can not be determined";
+ ErrorLogHelper.logError("500", message + ": " + e.getMessage());
+ LOGGER.error(message, e);
+ dbAvailable = null;
+ } finally {
+ if (transaction != null && !transaction.isClosed()) {
+ //check if transaction is open then close instead of flag
+ try {
+ transaction.rollback();
+ } catch (Exception e) {
+ String message = "Exception occurred while closing transaction";
+ LOGGER.error(message, e);
+ ErrorLogHelper.logError("500", message + ": " + e.getMessage());
+ }
+ }
+ }
+ return dbAvailable;
+ }
+
+ private void logDbState(CheckerType type) {
+ if (BooleanUtils.isTrue(isAaiGraphDbAvailableCache)) {
+ LOGGER.debug("Database is available from {} check.", type);
+ } else if (BooleanUtils.isFalse(isAaiGraphDbAvailableCache)) {
+ LOGGER.error("Database is NOT available from {} check.", type);
+ } else {
+ LOGGER.error("Database availability is UNKNOWN from {} check.", type);
+ }
+ }
+
+ private String getConfigurationValueOrDefault(String property, String defaultValue) {
+ String result;
+ try {
+ result = AAIConfig.get(property);
+ } catch (AAIException e) {
+ LOGGER.error(
+ "Unable to get defined configuration value for '{}' property, then default '{}' value is used",
+ property, defaultValue);
+ result = defaultValue;
+ }
+ return result;
+ }
+
+}
diff --git a/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties b/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
index 42fbbfc..4bcb2f3 100644
--- a/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
+++ b/aai-resources/src/main/resources/etc/appprops/aaiconfig.properties
@@ -157,4 +157,17 @@ aai.implied.delete.log.enabled=false
aai.implied.delete.whitelist.sdnc='vce'
aai.implied.delete.whitelist.ro='vserver'
-property.null.validation.enabled=true \ No newline at end of file
+property.null.validation.enabled=true
+
+#
+# AAI Graph DB checker task
+#
+
+# Indicator to enable or disable scheduled task (true/false)
+aai.graph.checker.task.enabled=false
+
+# Delay, in seconds, before the scheduled task is started, if enabled
+aai.graph.checker.task.delay=5
+
+# Period, in seconds, between two consecutive executions of the scheduled task, if enabled
+aai.graph.checker.task.period=10
diff --git a/aai-resources/src/main/resources/localhost-access-logback.xml b/aai-resources/src/main/resources/localhost-access-logback.xml
index a318796..48f5f92 100644
--- a/aai-resources/src/main/resources/localhost-access-logback.xml
+++ b/aai-resources/src/main/resources/localhost-access-logback.xml
@@ -23,18 +23,32 @@
-->
<configuration>
<property name="AJSC_HOME" value="${AJSC_HOME:-.}" />
+
+ <property name="maxHistory" value='7' />
+ <property name="totalSizeCap" value='1GB' />
+
<appender name="ACCESS"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${AJSC_HOME}/logs/ajsc-jetty/localhost_access.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${AJSC_HOME}/logs/ajsc-jetty/localhost_access.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${AJSC_HOME}/logs/ajsc-jetty/localhost_access.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder class="org.onap.aai.logging.CustomLogPatternLayoutEncoder">
<Pattern>%a %u %z [%t] "%m %U%q" %s %b %y %i{X-TransactionId} %i{X-FromAppId} %i{X-Forwarded-For} %i{X-AAI-SSL-Client-CN} %i{X-AAI-SSL-Client-OU} %i{X-AAI-SSL-Client-O} %i{X-AAI-SSL-Client-L} %i{X-AAI-SSL-Client-ST} %i{X-AAI-SSL-Client-C} %i{X-AAI-SSL-Client-NotBefore} %i{X-AAI-SSL-Client-NotAfter} %i{X-AAI-SSL-Client-DN} %D</Pattern>
</encoder>
</appender>
<appender-ref ref="ACCESS" />
+
+ <appender name="STDOUTACCESS" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="org.onap.aai.logging.CustomLogPatternLayoutEncoder">
+ <Pattern>%a %u %z [%t] "%m %U%q" %s %b %y %i{X-TransactionId} %i{X-FromAppId} %i{X-Forwarded-For} %i{X-AAI-SSL-Client-CN} %i{X-AAI-SSL-Client-OU} %i{X-AAI-SSL-Client-O} %i{X-AAI-SSL-Client-L} %i{X-AAI-SSL-Client-ST} %i{X-AAI-SSL-Client-C} %i{X-AAI-SSL-Client-NotBefore} %i{X-AAI-SSL-Client-NotAfter} %i{X-AAI-SSL-Client-DN} %D - "logType": "access"</Pattern>
+ </encoder>
+ </appender>
+
+ <appender-ref ref="STDOUTACCESS" />
</configuration>
<!--
diff --git a/aai-resources/src/main/resources/logback.xml b/aai-resources/src/main/resources/logback.xml
index ee2c903..c7a2d3e 100644
--- a/aai-resources/src/main/resources/logback.xml
+++ b/aai-resources/src/main/resources/logback.xml
@@ -26,6 +26,10 @@
<property resource="application.properties" />
+ <property name="maxHistory" value='7' />
+ <property name="totalSizeCap" value='1GB' />
+ <property name="queueSize" value='1000'/>
+
<property name="namespace" value="aai-resources"/>
<property name="AJSC_HOME" value="${AJSC_HOME:-.}" />
@@ -56,18 +60,13 @@
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
- <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
- <encoder>
- <pattern>
- %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
- </pattern>
- </encoder>
- </appender>
<appender name="SANE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDirectory}/rest/sane.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/sane.log.%d{yyyy-MM-dd}</fileNamePattern>
+ <fileNamePattern>${logDirectory}/rest/sane.log.%d{yyyy-MM-dd}.zip</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{1024} - %msg%n
@@ -76,7 +75,7 @@
</appender>
<appender name="asyncSANE" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="SANE" />
</appender>
@@ -84,7 +83,9 @@
<file>${logDirectory}/rest/metrics.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/metrics.log.%d{yyyy-MM-dd}</fileNamePattern>
+ <fileNamePattern>${logDirectory}/rest/metrics.log.%d{yyyy-MM-dd}.zip</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${metricPattern}</pattern>
@@ -92,7 +93,7 @@
</appender>
<appender name="asyncMETRIC" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="METRIC"/>
</appender>
@@ -107,7 +108,9 @@
<file>${logDirectory}/rest/debug.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/debug.log.%d{yyyy-MM-dd}</fileNamePattern>
+ <fileNamePattern>${logDirectory}/rest/debug.log.%d{yyyy-MM-dd}.zip</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${debugPattern}</pattern>
@@ -115,7 +118,7 @@
</appender>
<appender name="asyncDEBUG" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<appender-ref ref="DEBUG" />
<includeCallerData>true</includeCallerData>
</appender>
@@ -124,7 +127,9 @@
<file>${logDirectory}/rest/error.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/error.log.%d{yyyy-MM-dd}</fileNamePattern>
+ <fileNamePattern>${logDirectory}/rest/error.log.%d{yyyy-MM-dd}.zip</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
@@ -135,7 +140,7 @@
</appender>
<appender name="asyncERROR" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<appender-ref ref="ERROR"/>
</appender>
@@ -143,8 +148,10 @@
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${logDirectory}/rest/audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/audit.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/rest/audit.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${auditPattern}</pattern>
@@ -152,7 +159,7 @@
</appender>
<appender name="asyncAUDIT" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="AUDIT" />
</appender>
@@ -166,8 +173,10 @@
</filter>
<file>${logDirectory}/rest/translog.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/rest/translog.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/rest/translog.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${transLogPattern}</pattern>
@@ -175,7 +184,7 @@
</appender>
<appender name="asynctranslog" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="translog" />
</appender>
@@ -187,8 +196,10 @@
</filter>
<File>${logDirectory}/dmaapAAIEventConsumer/error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/error.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/error.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${errorPattern}</pattern>
@@ -205,8 +216,10 @@
</filter>
<File>${logDirectory}/dmaapAAIEventConsumer/debug.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/debug.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/debug.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${debugPattern}</pattern>
@@ -221,8 +234,10 @@
</filter>
<File>${logDirectory}/dmaapAAIEventConsumer/dmaap-transaction.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/dmaap-transaction.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/dmaap-transaction.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${auditPattern}</pattern>
@@ -237,8 +252,10 @@
</filter>
<File>${logDirectory}/dmaapAAIEventConsumer/metrics.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/metrics.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/dmaapAAIEventConsumer/metrics.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${metricPattern}</pattern>
@@ -251,8 +268,10 @@
</filter>
<file>${logDirectory}/external/external.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/external/external.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/external/external.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${debugPattern}</pattern>
@@ -265,18 +284,55 @@
</filter>
<file>${logDirectory}/auth/auth.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
- <fileNamePattern>${logDirectory}/auth/auth.log.%d{yyyy-MM-dd}
+ <fileNamePattern>${logDirectory}/auth/auth.log.%d{yyyy-MM-dd}.zip
</fileNamePattern>
+ <maxHistory>${maxHistory}</maxHistory>
+ <totalSizeCap>${totalSizeCap}</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss.SSSZ, UTC}[%thread] %-5level %logger{1024} - %msg%n</pattern>
</encoder>
</appender>
<appender name="asyncAUTH" class="ch.qos.logback.classic.AsyncAppender">
- <queueSize>1000</queueSize>
+ <queueSize>${queueSize}</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref="auth" />
</appender>
+
+ <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+ <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
+ <providers>
+ <timestamp><fieldName>timestamp</fieldName></timestamp>
+ <message/>
+ <mdc>
+ <fieldName>context</fieldName>
+ <excludeMdcKeyName>ServerIPAddress</excludeMdcKeyName>
+ <excludeMdcKeyName>EntryTimestamp</excludeMdcKeyName>
+ <excludeMdcKeyName>InvokeTimestamp</excludeMdcKeyName>
+ <excludeMdcKeyName>ErrorCode</excludeMdcKeyName>
+ <excludeMdcKeyName>ErrorDesc</excludeMdcKeyName>
+ </mdc>
+ <stackTrace>
+ <fieldName>exception</fieldName>
+ <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
+ <exclude>^sun\.reflect\..*\.invoke</exclude>
+ <exclude>^net\.sf\.cglib\.proxy\.MethodProxy\.invoke</exclude>
+ <rootCauseFirst>true</rootCauseFirst>
+ </throwableConverter>
+ </stackTrace>
+ <threadName><fieldName>thread</fieldName></threadName>
+ <loggerName>
+ <fieldName>logger</fieldName>
+ <shortenedLoggerNameLength>36</shortenedLoggerNameLength>
+ </loggerName>
+ <logLevel/>
+ <pattern>
+ <pattern>{"logType":"app"}</pattern>
+ </pattern>
+ </providers>
+ </encoder>
+ </appender>
+
<!-- logback internals logging -->
<logger name="ch.qos.logback.classic" level="WARN" />
diff --git a/aai-resources/src/test/java/org/onap/aai/AAISetup.java b/aai-resources/src/test/java/org/onap/aai/AAISetup.java
index 9a12007..dac7b60 100644
--- a/aai-resources/src/test/java/org/onap/aai/AAISetup.java
+++ b/aai-resources/src/test/java/org/onap/aai/AAISetup.java
@@ -1,4 +1,4 @@
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
@@ -17,6 +17,7 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
+
package org.onap.aai;
import org.apache.commons.io.IOUtils;
diff --git a/aai-resources/src/test/java/org/onap/aai/rest/util/EchoResponseTest.java b/aai-resources/src/test/java/org/onap/aai/rest/util/EchoResponseTest.java
index 9f55961..a8e5583 100644
--- a/aai-resources/src/test/java/org/onap/aai/rest/util/EchoResponseTest.java
+++ b/aai-resources/src/test/java/org/onap/aai/rest/util/EchoResponseTest.java
@@ -1,4 +1,4 @@
-/**
+/*
* ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
@@ -17,61 +17,56 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.rest.util;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-import org.onap.aai.AAISetup;
-import javax.ws.rs.core.*;
-import java.util.*;
+package org.onap.aai.rest.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import javax.ws.rs.core.*;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.AAISetup;
+import org.onap.aai.tasks.AaiGraphChecker;
+import org.onap.aai.tasks.AaiGraphChecker.CheckerType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.test.context.ContextConfiguration;
+
+@ContextConfiguration(classes = {AaiGraphChecker.class})
public class EchoResponseTest extends AAISetup {
+ private static final Logger logger = LoggerFactory.getLogger(EchoResponseTest.class);
protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
+ private static final String CHECK_DB_ACTION = "checkDB";
+ private static final String CHECK_DB_STATUS_NOW_ACTION = "checkDBNow";
- private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
-
- static {
- VALID_HTTP_STATUS_CODES.add(200);
- VALID_HTTP_STATUS_CODES.add(201);
- VALID_HTTP_STATUS_CODES.add(204);
- }
-
- private EchoResponse echoResponse;
+ private final EchoResponse echoResponse;
+ private final AaiGraphChecker aaiGraphCheckerMock = mock(AaiGraphChecker.class);
private HttpHeaders httpHeaders;
-
- private UriInfo uriInfo;
-
- private MultivaluedMap<String, String> headersMultiMap;
- private MultivaluedMap<String, String> queryParameters;
-
- private List<String> aaiRequestContextList;
-
private List<MediaType> outputMediaTypes;
- private static final Logger logger = LoggerFactory.getLogger(EchoResponseTest.class.getName());
+ public EchoResponseTest() {
+ this.echoResponse = new EchoResponse(aaiGraphCheckerMock);
+ }
@Before
- public void setup(){
+ public void setup() {
logger.info("Starting the setup for the integration tests of Rest Endpoints");
- echoResponse = new EchoResponse();
- httpHeaders = mock(HttpHeaders.class);
- uriInfo = mock(UriInfo.class);
-
- headersMultiMap = new MultivaluedHashMap<>();
- queryParameters = Mockito.spy(new MultivaluedHashMap<>());
+ MultivaluedMap<String, String> headersMultiMap = new MultivaluedHashMap<>();
+ MultivaluedMap<String, String> queryParameters = Mockito.spy(new MultivaluedHashMap<>());
headersMultiMap.add("X-FromAppId", "JUNIT");
headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
@@ -82,28 +77,28 @@ public class EchoResponseTest extends AAISetup {
outputMediaTypes = new ArrayList<>();
outputMediaTypes.add(APPLICATION_JSON);
- aaiRequestContextList = new ArrayList<>();
+ List<String> aaiRequestContextList = new ArrayList<>();
aaiRequestContextList.add("");
+ httpHeaders = mock(HttpHeaders.class);
when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
- when(httpHeaders.getRequestHeader("X-FromAppId")).thenReturn(Arrays.asList("JUNIT"));
- when(httpHeaders.getRequestHeader("X-TransactionId")).thenReturn(Arrays.asList("JUNIT"));
-
+ when(httpHeaders.getRequestHeader("X-FromAppId")).thenReturn(Collections.singletonList("JUNIT"));
+ when(httpHeaders.getRequestHeader("X-TransactionId")).thenReturn(Collections.singletonList("JUNIT"));
when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
+ when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
-
+ UriInfo uriInfo = mock(UriInfo.class);
when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
// TODO - Check if this is valid since RemoveDME2QueryParameters seems to be very unreasonable
Mockito.doReturn(null).when(queryParameters).remove(anyObject());
- when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
}
@Test
- public void testEchoResultWhenValidHeaders() throws Exception {
+ public void testEchoResultWhenValidHeaders() {
Response response = echoResponse.echoResult(httpHeaders, null, "");
@@ -112,7 +107,7 @@ public class EchoResponseTest extends AAISetup {
}
@Test
- public void testEchoResultWhenInValidHeadersThrowsBadRequest() throws Exception {
+ public void testEchoResultWhenInValidHeadersThrowsBadRequest() {
httpHeaders = mock(HttpHeaders.class);
Response response = echoResponse.echoResult(httpHeaders, null, "");
@@ -122,14 +117,71 @@ public class EchoResponseTest extends AAISetup {
}
@Test
- public void testEchoResultWhenValidHeadersButMediaTypeWrong() throws Exception {
+ public void testEchoResultWhenValidHeadersButMediaTypeWrong() {
- when(httpHeaders.getAcceptableMediaTypes()).thenThrow(new IllegalStateException())
- .thenReturn(outputMediaTypes);
+ when(httpHeaders.getAcceptableMediaTypes()).thenThrow(new IllegalStateException()).thenReturn(outputMediaTypes);
Response response = echoResponse.echoResult(httpHeaders, null, "");
assertNotNull(response);
assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
}
+
+ @Test
+ public void testCheckDbAction_CachedSuccess() {
+ // Prepare
+ when(aaiGraphCheckerMock.isAaiGraphDbAvailable(CheckerType.CACHED)).thenReturn(Boolean.TRUE);
+ // Run
+ Response response = echoResponse.echoResult(httpHeaders, null, CHECK_DB_ACTION);
+ // Verify
+ verify(aaiGraphCheckerMock, never()).isAaiGraphDbAvailable(CheckerType.ACTUAL);
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void testCheckDbAction_CachedFailure() {
+ // Prepare
+ when(aaiGraphCheckerMock.isAaiGraphDbAvailable(CheckerType.CACHED)).thenReturn(Boolean.FALSE);
+ // Run
+ Response response = echoResponse.echoResult(httpHeaders, null, CHECK_DB_ACTION);
+ // Verify
+ verify(aaiGraphCheckerMock, never()).isAaiGraphDbAvailable(CheckerType.ACTUAL);
+ assertNotNull(response);
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void testCheckDbNowAction_Success() {
+ // Prepare
+ when(aaiGraphCheckerMock.isAaiGraphDbAvailable(CheckerType.ACTUAL)).thenReturn(Boolean.TRUE);
+ // Run
+ Response response = echoResponse.echoResult(httpHeaders, null, CHECK_DB_STATUS_NOW_ACTION);
+ // Verify
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void testCheckDbNowAction_Failure() {
+ // Prepare
+ when(aaiGraphCheckerMock.isAaiGraphDbAvailable(CheckerType.ACTUAL)).thenReturn(Boolean.FALSE);
+ // Run
+ Response response = echoResponse.echoResult(httpHeaders, null, CHECK_DB_STATUS_NOW_ACTION);
+ // Verify
+ assertNotNull(response);
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
+ public void testCheckDbNowAction_Unknown() {
+ // Prepare
+ when(aaiGraphCheckerMock.isAaiGraphDbAvailable(CheckerType.ACTUAL)).thenReturn(null);
+ // Run
+ Response response = echoResponse.echoResult(httpHeaders, null, CHECK_DB_STATUS_NOW_ACTION);
+ // Verify
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
+ }
+
}
diff --git a/aai-resources/src/test/java/org/onap/aai/task/AaiGraphCheckerTest.java b/aai-resources/src/test/java/org/onap/aai/task/AaiGraphCheckerTest.java
new file mode 100644
index 0000000..11a5134
--- /dev/null
+++ b/aai-resources/src/test/java/org/onap/aai/task/AaiGraphCheckerTest.java
@@ -0,0 +1,70 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2022 Bell Canada
+ * ================================================================================
+ * 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.onap.aai.task;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.aai.AAISetup;
+import org.onap.aai.tasks.AaiGraphChecker;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+
+@ContextConfiguration(classes = {AaiGraphChecker.class})
+@TestPropertySource(properties = "aai.graph.checker.task.enabled=true")
+public class AaiGraphCheckerTest extends AAISetup {
+
+ @Autowired
+ private AaiGraphChecker subject;
+
+ @Test
+ public void testIsAaiGraphDbAvailable_Actual() {
+ // Run
+ Boolean result = subject.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.ACTUAL);
+ // Verify
+ assertNotNull(result);
+ assertTrue(result);
+ }
+
+ @Test
+ public void testIsAaiGraphDbAvailable_CachedAfterClear() {
+ // Prepare
+ subject.clearDbAvailabilityCachedIndicator();
+ // Run
+ Boolean result = subject.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.CACHED);
+ // Verify
+ assertNull(result);
+ }
+
+ @Test
+ public void testIsAaiGraphDbAvailable_CachedAfterActual() {
+ // Prepare
+ subject.clearDbAvailabilityCachedIndicator();
+ subject.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.ACTUAL);
+ // Run
+ Boolean result = subject.isAaiGraphDbAvailable(AaiGraphChecker.CheckerType.CACHED);
+ // Verify
+ assertNotNull(result);
+ assertTrue(result);
+ }
+
+}
diff --git a/aai-resources/src/test/resources/etc/appprops/aaiconfig.properties b/aai-resources/src/test/resources/etc/appprops/aaiconfig.properties
index a279738..76167b2 100644
--- a/aai-resources/src/test/resources/etc/appprops/aaiconfig.properties
+++ b/aai-resources/src/test/resources/etc/appprops/aaiconfig.properties
@@ -56,3 +56,16 @@ aai.run.migrations=false
aai.jms.enable=false
property.null.validation.enabled=true
+
+#
+# AAI Graph DB checker task
+#
+
+# Indicator to enable or disable scheduled task (true/false)
+aai.graph.checker.task.enabled=true
+
+# Delay, in seconds, before the scheduled task is started, if enabled
+aai.graph.checker.task.delay=30
+
+# Period, in seconds, between two consecutive executions of the scheduled task, if enabled
+aai.graph.checker.task.period=60