Moving Historical Queries to spring boot 53/40753/2
authorBansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
Tue, 3 Apr 2018 16:31:43 +0000 (12:31 -0400)
committerBansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
Tue, 3 Apr 2018 17:00:34 +0000 (13:00 -0400)
Change-Id: If4042f3b19b25b086e8f0c4b3723afe9839d994a
Issue-ID: AAI-802
Signed-off-by: Bansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
21 files changed:
pom.xml
src/main/java/org/onap/aai/datarouter/Application.java
src/main/java/org/onap/aai/datarouter/JerseyConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java [deleted file]
src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java [deleted file]
src/main/java/org/onap/aai/datarouter/exception/DataRouterException.java [moved from src/test/java/org/onap/aai/datarouter/exception/DataRouterExceptionTest.java with 52% similarity]
src/main/java/org/onap/aai/datarouter/logging/DataRouterMsgs.java
src/main/java/org/onap/aai/datarouter/logging/LoggingUtil.java [new file with mode: 0644]
src/main/java/org/onap/aai/datarouter/query/ChameleonResponseBuiler.java
src/main/java/org/onap/aai/datarouter/query/ChameleonRouter.java
src/main/java/org/onap/aai/datarouter/query/ChampRouter.java
src/main/java/org/onap/aai/datarouter/query/QueryRouter.java
src/main/java/org/onap/aai/datarouter/query/RestClientConfig.java [new file with mode: 0644]
src/main/java/org/onap/aai/datarouter/service/EchoService.java
src/main/java/org/onap/aai/datarouter/service/HistoricalQueryService.java [new file with mode: 0644]
src/main/resources/application.properties
src/main/resources/logging/DataRouterMsgs.properties
src/test/java/org/onap/aai/datarouter/query/ChameleonRouterTest.java [new file with mode: 0644]
src/test/java/org/onap/aai/datarouter/query/ChampRouterTest.java [new file with mode: 0644]
src/test/resources/chameleon-response.json [new file with mode: 0644]
src/test/resources/champ-response.json [new file with mode: 0644]

diff --git a/pom.xml b/pom.xml
index 03c5d8d..fc5dd83 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -70,6 +70,10 @@ limitations under the License.
    </properties>
 
    <dependencies>
+    <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jersey</artifactId>           
+        </dependency>
     <dependency>
             <groupId>ch.qos.logback</groupId>
             <artifactId>logback-core</artifactId>
@@ -89,11 +93,7 @@ limitations under the License.
          <groupId>org.apache.camel</groupId>
          <artifactId>camel-spring-boot-starter</artifactId>
       </dependency>
-      <dependency>
-         <groupId>org.apache.camel</groupId>
-         <artifactId>camel-core</artifactId>
-         <version>2.20.1</version>
-      </dependency>
+
       <dependency>
          <groupId>org.apache.camel</groupId>
          <artifactId>camel-servlet-starter</artifactId>
@@ -107,8 +107,7 @@ limitations under the License.
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
-
-      </dependency>
+      </dependency>      
       <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter</artifactId>
@@ -122,6 +121,11 @@ limitations under the License.
          <artifactId>javax.ws.rs-api</artifactId>
          <version>2.0.1</version>
       </dependency>
+         <dependency>
+      <groupId>org.eclipse.jetty</groupId>
+      <artifactId>jetty-security</artifactId>
+      <version>9.3.8.RC0</version>
+   </dependency>
       <dependency>
          <groupId>org.powermock</groupId>
          <artifactId>powermock-module-junit4</artifactId>
@@ -299,12 +303,12 @@ limitations under the License.
             </configuration>
          </plugin>
          <!-- license plugin -->
-         <!-- Uncomment this to add a license header to every source file 
+         <!-- Uncomment this to add a license header to every source file -->
             <plugin> <groupId>com.mycila</groupId> <artifactId>license-maven-plugin</artifactId> 
             <version>3.0</version> <configuration> <header>License.txt</header> <includes> 
             <include>src/main/java/**</include> <include>src/test/java/**</include> </includes> 
             </configuration> <executions> <execution> <goals> <goal>format</goal> </goals> 
-            <phase>process-sources</phase> </execution> </executions> </plugin> -->
+            <phase>process-sources</phase> </execution> </executions> </plugin> 
          <plugin>
             <groupId>org.sonatype.plugins</groupId>
             <artifactId>nexus-staging-maven-plugin</artifactId>
index dfd8144..3ea6ab8 100644 (file)
  */
 package org.onap.aai.datarouter;
 
-import org.springframework.boot.SpringApplication;
+import java.util.HashMap;
+
+import org.eclipse.jetty.util.security.Password;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.support.SpringBootServletInitializer;
 
 
 @SpringBootApplication
-public class Application {
+public class Application extends SpringBootServletInitializer{
 
     public static void main(String[] args) {
-        SpringApplication.run(Application.class, args);
+      String keyStorePassword = System.getProperty("KEY_STORE_PASSWORD");
+      if(keyStorePassword==null || keyStorePassword.isEmpty()){
+        throw new RuntimeException("Env property KEY_STORE_PASSWORD not set");
+      }
+      HashMap<String, Object> props = new HashMap<>();
+      props.put("server.ssl.key-store-password", Password.deobfuscate(keyStorePassword));
+      new Application().configure(new SpringApplicationBuilder(Application.class).properties(props)).run(args);
+      
+       
     }
 
 }
\ No newline at end of file
diff --git a/src/main/java/org/onap/aai/datarouter/JerseyConfiguration.java b/src/main/java/org/onap/aai/datarouter/JerseyConfiguration.java
new file mode 100644 (file)
index 0000000..04e8cad
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter;
+
+import javax.ws.rs.ApplicationPath;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.onap.aai.datarouter.service.EchoService;
+import org.onap.aai.datarouter.service.HistoricalQueryService;
+import org.springframework.stereotype.Component;
+
+
+@Component
+@ApplicationPath("/")
+public class JerseyConfiguration extends ResourceConfig
+{
+   public JerseyConfiguration()
+   {
+       register(EchoService.class);
+       register(HistoricalQueryService.class);
+      
+   }
+}
\ No newline at end of file
diff --git a/src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java b/src/main/java/org/onap/aai/datarouter/exception/BaseDataRouterException.java
deleted file mode 100644 (file)
index c256da3..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 Amdocs
- * ================================================================================
- * 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.datarouter.exception;
-
-/*
- * COPYRIGHT NOTICE: Copyright (c) 2016 Team Pacifica (Amdocs & AT&T) The contents and intellectual
- * property contained herein, remain the property of Team Pacifica (Amdocs & AT&T).
- */
-
-import java.util.Locale;
-
-/**
- * Base SMAdaptor exception class.
- */
-public class BaseDataRouterException extends Exception {
-
-  /** Force serialVersionUID. */
-  private static final long serialVersionUID = -6663403070792969748L;
-
-  /** Default locale. */
-  public static final Locale LOCALE = Locale.US;
-
-  /** Exception id. */
-  private final String id;
-
-  /**
-   * Constructor.
-   * 
-   * @param id the incoming id.
-   */
-  public BaseDataRouterException(final String id) {
-    super();
-    this.id = id;
-  }
-
-  /**
-   * Constructor.
-   * 
-   * @param id the incoming id
-   * @param message the incoming message
-   */
-  public BaseDataRouterException(final String id, final String message) {
-    super(message);
-    this.id = id;
-  }
-
-  /**
-   * Constructor.
-   * 
-   * @param id the incoming id
-   * @param message the incoming message
-   * @param cause the incoming throwable
-   */
-  public BaseDataRouterException(final String id, final String message, final Throwable cause) {
-    super(message, cause);
-    this.id = id;
-  }
-
-  /**
-   * Get the exception id.
-   * 
-   * @return the exception id
-   */
-  public String getId() {
-    return this.id;
-  }
-}
diff --git a/src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java b/src/main/java/org/onap/aai/datarouter/exception/DataRouterError.java
deleted file mode 100644 (file)
index 6ca4bd8..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 Amdocs
- * ================================================================================
- * 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.datarouter.exception;
-
-/*
- * COPYRIGHT NOTICE: Copyright (c) 2016 Team Pacifica (Amdocs & AT&T) The contents and intellectual
- * property contained herein, remain the property of Team Pacifica (Amdocs & AT&T).
- */
-
-import java.text.MessageFormat;
-
-import javax.ws.rs.core.Response.Status;
-
-/**
- * DL enum for error conditions.
- */
-public enum DataRouterError {
-
-  /** Parsing exceptions - Range 100..199. */
-  DL_PARSE_100("DL-100", "Unable to find resource {0} in the model", Status.BAD_REQUEST), 
-  DL_PARSE_101("DL-101", "Unable to parse ", Status.BAD_REQUEST), 
-  DL_PARSE_102("DL-102", "Sot Filter error: {0} ", Status.INTERNAL_SERVER_ERROR), 
-  DL_PARSE_103("DL-103", "URL Parsing error: {0} ", Status.BAD_REQUEST), 
-  DL_PARSE_104("DL-104", "Missing Ids filter: {0} ", Status.BAD_REQUEST), 
-  DL_PARSE_105("DL-105", "Invalid Ids filter: {0} ", Status.BAD_REQUEST),
-
-  /** Validation exceptions - Range 200..299. */
-  DL_VALIDATION_200("DL-200", "Missing X-TransactionId in header ", Status.BAD_REQUEST),
-
-  /** Other components integration errors - Range 300..399. */
-  DL_INTEGRATION_300("DL-300", "Unable to decorate Graph ", Status.INTERNAL_SERVER_ERROR),
-
-  /** Environment related exceptions - Range 400..499. */
-  DL_ENV_400("DL-400", "Unable to find file {0} ", Status.INTERNAL_SERVER_ERROR), 
-  DL_ENV_401("DL-401", "Unable to Load OXM Models", Status.INTERNAL_SERVER_ERROR),
-
-  /** Other components integration errors - Range 500..599. */
-  DL_AUTH_500("DL-500", "Unable to authorize User ", Status.FORBIDDEN);
-
-  /** The error id. */
-  private String id;
-  /** The error message. */
-  private String message;
-  /** The error http return code. */
-  private Status status;
-
-  /**
-   * Constructor.
-   * 
-   * @param id the error id
-   * @param message the error message
-   */
-  DataRouterError(final String id, final String message, final Status status) {
-    this.id = id;
-    this.message = message;
-    this.status = status;
-  }
-
-  /**
-   * Get the id.
-   * 
-   * @return the error id
-   */
-  public String getId() {
-    return this.id;
-  }
-
-  /**
-   * Get the message.
-   * 
-   * @param args the error arguments
-   * @return the error message
-   */
-  public String getMessage(final Object... args) {
-    final MessageFormat formatter = new MessageFormat("");
-    formatter.applyPattern(this.message);
-    return formatter.format(args);
-  }
-
-  public Status getHttpStatus() {
-    return this.status;
-  }
-
-}
@@ -1,49 +1,59 @@
-/**\r
- * ============LICENSE_START=======================================================\r
- * org.onap.aai\r
- * ================================================================================\r
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.\r
- * Copyright © 2017-2018 Amdocs\r
- * ================================================================================\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *       http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- * ============LICENSE_END=========================================================\r
- */\r
-package org.onap.aai.datarouter.exception;\r
-\r
-import org.junit.Assert;\r
-import org.junit.Test;\r
-\r
-import javax.ws.rs.core.Response;\r
-\r
-public class DataRouterExceptionTest {\r
-\r
-    @Test\r
-    public void testDataRouterError(){\r
-        DataRouterError error1 = DataRouterError.DL_PARSE_100;\r
-        Assert.assertEquals("DL-100", error1.getId());\r
-        Assert.assertNotNull(error1.getMessage());\r
-        Assert.assertEquals(Response.Status.BAD_REQUEST, error1.getHttpStatus());\r
-    }\r
-\r
-    @Test\r
-    public void testBaseDataRouterException(){\r
-        BaseDataRouterException exp1 = new BaseDataRouterException("id-1");\r
-        Assert.assertEquals(exp1.getId(), "id-1");\r
-\r
-        BaseDataRouterException exp2 = new BaseDataRouterException("id-1", "test-error");\r
-        Assert.assertEquals(exp2.getId(), "id-1");\r
-\r
-        BaseDataRouterException exp3 = new BaseDataRouterException("id-1", "test-error", new Throwable());\r
-        Assert.assertEquals(exp3.getId(), "id-1");\r
-    }\r
-}\r
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.exception;
+
+import javax.ws.rs.core.Response.Status;
+
+public class DataRouterException extends Exception {
+
+  private static final long serialVersionUID = 8162385108397238865L;
+
+  private Status httpStatus;
+
+  public DataRouterException() {
+  }
+
+  public DataRouterException(String message, Status httpStatus) {
+    super(message);
+    this.setHttpStatus(httpStatus);
+  }
+
+  public DataRouterException(Throwable cause) {
+    super(cause);
+  }
+
+  public DataRouterException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  public DataRouterException(String message, Throwable cause, boolean enableSuppression,
+                       boolean writableStackTrace) {
+    super(message, cause, enableSuppression, writableStackTrace);
+  }
+
+  public Status getHttpStatus() {
+    return httpStatus;
+  }
+
+  public void setHttpStatus(Status httpStatus) {
+    this.httpStatus = httpStatus;
+  }
+}
index 93f4c54..f0d6541 100644 (file)
@@ -26,6 +26,12 @@ import org.onap.aai.cl.eelf.LogMessageEnum;
 
 public enum DataRouterMsgs implements LogMessageEnum {
 
+  /**
+   * Arguments: {0}  = HTTP request type, {1} = time to process in milliseconds
+   */
+  PROCESSED_REQUEST,
+
   /** Data Layer Service started. */
   SERVICE_STARTED,
 
diff --git a/src/main/java/org/onap/aai/datarouter/logging/LoggingUtil.java b/src/main/java/org/onap/aai/datarouter/logging/LoggingUtil.java
new file mode 100644 (file)
index 0000000..e29af73
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.logging;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+
+import org.onap.aai.cl.api.LogFields;
+import org.onap.aai.cl.api.LogLine;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+import org.slf4j.MDC;
+
+public class LoggingUtil {
+  public static void initMdcContext(HttpServletRequest httpReq, HttpHeaders headers) {
+    String fromIp = httpReq.getRemoteAddr();
+    String fromAppId = "";
+    String transId = null;
+
+    if (headers.getRequestHeaders().getFirst("X-FromAppId") != null) {
+      fromAppId = headers.getRequestHeaders().getFirst("X-FromAppId");
+    }
+
+    if ((headers.getRequestHeaders().getFirst("X-TransactionId") == null)
+        || headers.getRequestHeaders().getFirst("X-TransactionId").isEmpty()) {
+      transId = java.util.UUID.randomUUID().toString();
+    } else {
+      transId = headers.getRequestHeaders().getFirst("X-TransactionId");
+    }
+
+    MdcContext.initialize(transId, DataRouterConstants.DATA_ROUTER_SERVICE_NAME, "", fromAppId,
+        fromIp);
+  }
+
+  public static void logRestRequest(Logger logger, Logger auditLogger, HttpServletRequest req, Response response) {
+    String respStatusString = "";
+    if (Response.Status.fromStatusCode(response.getStatus()) != null) {
+      respStatusString = Response.Status.fromStatusCode(response.getStatus()).toString();
+    }
+
+    // Generate error log
+    logger.info(DataRouterMsgs.PROCESS_REST_REQUEST, req.getMethod(), req.getRequestURL().toString(),
+        req.getRemoteHost(), Integer.toString(response.getStatus()));
+
+    // Generate audit log.
+    auditLogger.info(DataRouterMsgs.PROCESS_REST_REQUEST,
+        new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, response.getStatus())
+            .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, respStatusString),
+        (req != null) ? req.getMethod() : "Unknown", (req != null) ? req.getRequestURL().toString() : "Unknown",
+        (req != null) ? req.getRemoteHost() : "Unknown", Integer.toString(response.getStatus()) + " payload: "
+            + (response.getEntity() == null ? "" : response.getEntity().toString()));
+    MDC.clear();
+  }
+
+  public static String setDuration(long startTime, long stopTime) {
+    return String.valueOf(stopTime - startTime);
+  }
+}
index d319c48..502fbf2 100644 (file)
@@ -24,7 +24,10 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import javax.ws.rs.core.Response.Status;
+
 import org.apache.camel.Exchange;
+import org.onap.aai.datarouter.exception.DataRouterException;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -36,14 +39,13 @@ public class ChameleonResponseBuiler  {
   private static final String TARGET = "target";
   private static final String TYPE = "type";
 
-  public static void buildEntity(Exchange exchange, String id){
-    String response = exchange.getIn().getBody().toString();
+  public static String buildEntity(String chameleonResponse, String id) throws DataRouterException{
+    
     JsonParser parser = new JsonParser();
-    JsonObject root = parser.parse(response).getAsJsonObject();
+    JsonObject root = parser.parse(chameleonResponse).getAsJsonObject();
     JsonObject champResponse = new JsonObject();
     if (!root.has(TYPE)) {
-      exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
-      return ;
+      throw new DataRouterException("Chameloen response does not have type : "+chameleonResponse , Status.BAD_REQUEST);
     }
     champResponse.addProperty("key", id);
     champResponse.addProperty(TYPE, root.get(TYPE).getAsString());
@@ -66,16 +68,19 @@ public class ChameleonResponseBuiler  {
     
     champResponse.add("properties", props);
 
-    exchange.getIn().setBody(champResponse.toString());
+    return champResponse.toString();
     
   }
   
  
-  public static void buildObjectRelationship(Exchange exchange, String id){
+  public static String buildObjectRelationship(String chameleonResponse, String id){
     //TODO: implement when chameleon supports this query     
+    return "[]";
   }
-  public static void buildCollection(Exchange exchange){
+  public static String buildCollection(String chameleonResponse){
     //TODO: implement when chameleon supports this query   
+    return "[]";
+    
   }
   
  
index 2df2524..4e9f75b 100644 (file)
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
-package  org.onap.aai.datarouter.query;
+package org.onap.aai.datarouter.query;
 
 import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import javax.ws.rs.BadRequestException;
+import javax.annotation.PostConstruct;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
 
-import org.apache.camel.Exchange;
-import org.apache.camel.RuntimeCamelException;
-import org.onap.aai.rest.RestClientEndpoint;
+import org.eclipse.jetty.util.security.Password;
 import org.onap.aai.cl.api.Logger;
 import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.datarouter.exception.DataRouterException;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
 
-public class ChameleonRouter extends QueryRouter {
+@Component
+@Qualifier("chameleon")
+public class ChameleonRouter implements QueryRouter {
 
   Logger logger = LoggerFactory.getInstance().getLogger(ChameleonRouter.class.getName());
 
   private String chameleonBaseURL;
 
+  private RestClient restClient ;
+
   private enum ChameleonAction {
     GET_OBJECT_BY_ID, GET_REL_BY_ID, GET_OBJECT_RELS, GET_OBJECTS_BY_FILTER, GET_RELS_BY_FILTER
   };
@@ -48,13 +62,26 @@ public class ChameleonRouter extends QueryRouter {
   private static final Pattern QUERY_OBJECT_ID_URL_MATCH = Pattern.compile("/objects/(.*)");
   private static final Pattern QUERY_REL_ID_URL_MATCH = Pattern.compile("/relationships/(.*)");
 
-  private static final String ECOMP_QUERY_ID = "ECOMP_QUERY_ID";
-  private static final String ECOMP_QUERY_TYPE = "ECOMP_QUERY_TYPE";
 
-  public ChameleonRouter(String chameleonBaseURL) {
+  public ChameleonRouter(){}
+  
+  
+  public ChameleonRouter(String chameleonBaseURL, RestClientConfig config) {   
+    this.chameleonBaseURL = chameleonBaseURL;
+    this.restClient = new RestClient().validateServerHostname(false).validateServerCertChain(true)
+        .clientCertFile(config.getCertPath())
+        .clientCertPassword(Password.deobfuscate(config.getCertPassword()))
+        .trustStore(config.getTrustStorePath())
+        .connectTimeoutMs(config.getConnectionTimeout())
+        .readTimeoutMs(config.getReadTimeout());
+    validate();
+  }
+
+  
+  public void validate() {
     String baseURL = chameleonBaseURL.endsWith("/") ? chameleonBaseURL.substring(0, chameleonBaseURL.length() - 1)
         : chameleonBaseURL;
-    if (checkRecursion(baseURL)) {
+    if (baseURL.contains(DATA_ROUTER_PORT)) {
       logger.error(QueryMsgs.QUERY_ERROR,
           "Invalid chameleonBaseURL : Can't re-route back to DataRouter " + chameleonBaseURL);
       throw new InvalidParameterException(
@@ -63,17 +90,6 @@ public class ChameleonRouter extends QueryRouter {
     this.chameleonBaseURL = baseURL;
   }
 
-  public void setQueryRequest(Exchange exchange) {
-    setMDC(exchange);
-    ChameleonAction action = resolveChameleonAction(exchange);
-    String ecompUrl = buildUrl(exchange, action);
-    logger.info(QueryMsgs.QUERY_INFO, "Routing request to Chameleon service URL: " + ecompUrl);
-    exchange.getIn().setHeader(RestClientEndpoint.IN_HEADER_URL, ecompUrl);
-    exchange.getIn().setHeader("X-FromAppId", SERVICE_NAME);
-    exchange.getIn().setHeader("X-TransactionId", getTxId(exchange));
-
-  }
-
   private boolean urlMatcher(Pattern p, String url) {
     Matcher m = p.matcher(url);
     if (m.matches() && !m.group(1).contains("/")) {
@@ -83,40 +99,39 @@ public class ChameleonRouter extends QueryRouter {
     }
   }
 
-  private ChameleonAction resolveChameleonAction(Exchange exchange) {
-    String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
-    path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
+  private ChameleonAction resolveChameleonAction(String urlContext) throws DataRouterException {
+
+    urlContext = urlContext.endsWith("/") ? urlContext.substring(0, urlContext.length() - 1) : urlContext;
     ChameleonAction action;
 
-    if (urlMatcher(QUERY_OBJECT_FILTER_URL_MATCH, path)) {
+    if (urlMatcher(QUERY_OBJECT_FILTER_URL_MATCH, urlContext)) {
       action = ChameleonAction.GET_OBJECTS_BY_FILTER;
-    } else if (urlMatcher(QUERY_REL_FILTER_URL_MATCH, path)) {
+    } else if (urlMatcher(QUERY_REL_FILTER_URL_MATCH, urlContext)) {
       action = ChameleonAction.GET_RELS_BY_FILTER;
-    } else if (urlMatcher(QUERY_OBJECT_REL_URL_MATCH, path)) {
+    } else if (urlMatcher(QUERY_OBJECT_REL_URL_MATCH, urlContext)) {
       action = ChameleonAction.GET_OBJECT_RELS;
-    } else if (urlMatcher(QUERY_OBJECT_ID_URL_MATCH, path)) {
+    } else if (urlMatcher(QUERY_OBJECT_ID_URL_MATCH, urlContext)) {
       action = ChameleonAction.GET_OBJECT_BY_ID;
-    } else if (urlMatcher(QUERY_REL_ID_URL_MATCH, path)) {
+    } else if (urlMatcher(QUERY_REL_ID_URL_MATCH, urlContext)) {
       action = ChameleonAction.GET_REL_BY_ID;
     } else {
-      exchange.getIn().setHeader(ChameleonErrorProcessor.ECOMP_QUERY_ERROR_CODE, 404);
-      throw new RuntimeCamelException();
+
+      throw new DataRouterException("", Status.NOT_FOUND);
     }
     return action;
   }
 
-  private String buildUrl(Exchange exchange, ChameleonAction action) {
-    String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
-    path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
-    String queryParams = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
+  private String buildUrl(String urlContext, String queryParams, ChameleonAction action) {
+
+    urlContext = urlContext.endsWith("/") ? urlContext.substring(0, urlContext.length() - 1) : urlContext;
     String ecompUrl = "";
     String ID = "";
 
     switch (action) {
     case GET_OBJECT_BY_ID:
-      ID = path.substring(path.lastIndexOf("/") + 1, path.length());
+      ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
       if (ID == null || ID.isEmpty()) {
-        throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
+        throw new IllegalArgumentException("Invalid URI path with no Object ID: " + urlContext);
       } else {
         if (queryParams != null && !queryParams.isEmpty()) {
           ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
@@ -125,14 +140,13 @@ public class ChameleonRouter extends QueryRouter {
           ecompUrl = chameleonBaseURL + "/" + ID;
         }
       }
-      exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
-      exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_BY_ID);
+
       break;
 
     case GET_REL_BY_ID:
-      ID = path.substring(path.lastIndexOf("/") + 1, path.length());
+      ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
       if (ID == null || ID.isEmpty()) {
-        throw new IllegalArgumentException("Invalid URI path with no Relationship ID: " + path);
+        throw new IllegalArgumentException("Invalid URI path with no Relationship ID: " + urlContext);
       } else {
         if (queryParams != null && !queryParams.isEmpty()) {
           ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
@@ -141,14 +155,13 @@ public class ChameleonRouter extends QueryRouter {
           ecompUrl = chameleonBaseURL + "/" + ID;
         }
       }
-      exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
-      exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_REL_BY_ID);
+
       break;
 
     case GET_OBJECT_RELS:
-      ID = path.substring(path.lastIndexOf("/") + 1, path.length());
+      ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
       if (ID == null || ID.isEmpty()) {
-        throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
+        throw new IllegalArgumentException("Invalid URI path with no Object ID: " + urlContext);
       } else {
         if (queryParams != null && !queryParams.isEmpty()) {
           // TODO: Fix the URL for getting object relations when Chameloen
@@ -159,8 +172,7 @@ public class ChameleonRouter extends QueryRouter {
           ecompUrl = chameleonBaseURL + "/relations" + ID;
         }
       }
-      exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
-      exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_RELS);
+
       break;
 
     case GET_OBJECTS_BY_FILTER:
@@ -171,7 +183,7 @@ public class ChameleonRouter extends QueryRouter {
       } else {
         ecompUrl = chameleonBaseURL + "/filter";
       }
-      exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECTS_BY_FILTER);
+
       break;
 
     case GET_RELS_BY_FILTER:
@@ -182,7 +194,7 @@ public class ChameleonRouter extends QueryRouter {
       } else {
         ecompUrl = chameleonBaseURL + "/filter";
       }
-      exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_RELS_BY_FILTER);
+
       break;
 
     }
@@ -190,86 +202,83 @@ public class ChameleonRouter extends QueryRouter {
     return ecompUrl;
   }
 
-  public void setQueryResponse(Exchange exchange) {
-    parseResponse(exchange);
-    adjustHeaders(exchange);
-  }
-
-  private void adjustHeaders(Exchange exchange) {
-    // Remove the internal heders
-    exchange.getIn().removeHeader(ECOMP_QUERY_ID);
-    exchange.getIn().removeHeader(ECOMP_QUERY_TYPE);
-  }
+  private String parseResponse(String urlContext, OperationResult result, ChameleonAction action)
+      throws DataRouterException {
 
-  private void parseResponse(Exchange exchange) throws BadRequestException {
-
-    ChameleonAction action = exchange.getIn().getHeader(ECOMP_QUERY_TYPE, ChameleonAction.class);
-    Integer httpResponseCode = exchange.getIn().getHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_CODE, Integer.class);
-    String ID = "";
+    Integer httpResponseCode = result.getResultCode();
+    String ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
 
     switch (action) {
     case GET_OBJECT_BY_ID:
       if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-        ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
         if (ID == null || ID.isEmpty()) {
-          exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
+          throw new DataRouterException("", Status.BAD_REQUEST);
         } else {
-          ChameleonResponseBuiler.buildEntity(exchange, ID);
+          return ChameleonResponseBuiler.buildEntity(result.getResult(), ID);
         }
       } else {
-        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
+        throw new DataRouterException("", Status.fromStatusCode(httpResponseCode));
       }
-      break;
+
     case GET_REL_BY_ID:
       if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-        ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
+
         if (ID == null || ID.isEmpty()) {
-          exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
+          throw new DataRouterException("", Status.BAD_REQUEST);
         } else {
-          ChameleonResponseBuiler.buildEntity(exchange, ID);
+          return ChameleonResponseBuiler.buildEntity(result.getResult(), ID);
         }
       } else {
-        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
+        throw new DataRouterException("", Status.fromStatusCode(httpResponseCode));
       }
-      break;
+
     case GET_OBJECT_RELS:
-      if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-        ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
-        if (ID == null || ID.isEmpty()) {
-          exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
-        } else {
-          ChameleonResponseBuiler.buildObjectRelationship(exchange, ID);
-        }
+
+      // TODO:Return 200 with empty body for now until chameleon supports this
+      // query
+      if (ID == null || ID.isEmpty()) {
+        throw new DataRouterException("", Status.BAD_REQUEST);
       } else {
-        // TODO:Return 200 with empty body for now until chameleon supports this
-        // query
-        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
-        exchange.getIn().setBody("[]");
+        return ChameleonResponseBuiler.buildObjectRelationship(result.getResult(), ID);
       }
-      break;
+
     case GET_OBJECTS_BY_FILTER:
-      if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-        ChameleonResponseBuiler.buildCollection(exchange);
-      } else {
-        // TODO:Return 200 with empty body for now until chameleon supports this
-        // query
-        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
-        exchange.getIn().setBody("[]");
-      }
-      break;
+      // TODO:Return 200 with empty body for now until chameleon supports this
+      // query
+      return ChameleonResponseBuiler.buildCollection(result.getResult());
+
     case GET_RELS_BY_FILTER:
-      if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-        ChameleonResponseBuiler.buildCollection(exchange);
-      } else {
-        // TODO:Return 200 with empty body for now until chameleon supports this
-        // query
-        exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
-        exchange.getIn().setBody("[]");
-      }
-      break;
+      // TODO:Return 200 with empty body for now until chameleon supports this
+      // query
+      return ChameleonResponseBuiler.buildCollection(result.getResult());
+    default:
+      throw new DataRouterException("", Status.NOT_FOUND);
+
+    }
+
+  }
 
+  @Override
+  public String process(String urlContext, String queryParams, Map<String, List<String>> headers)
+      throws DataRouterException {
+    String response;
+    ChameleonAction action = resolveChameleonAction(urlContext);
+    String chameleonURL = buildUrl(urlContext, queryParams, action);
+    logger.info(QueryMsgs.QUERY_INFO, "Routing request to Chameleon service URL: " + chameleonURL);
+
+    headers = headers == null ? new HashMap<String, List<String>>() : headers;
+    headers.put("X-FromAppId", Arrays.asList(DataRouterConstants.DATA_ROUTER_SERVICE_NAME));
+    OperationResult result = restClient.get(chameleonURL, headers, MediaType.APPLICATION_JSON_TYPE);
+
+    try {
+      response = parseResponse(urlContext, result, action);
+    } catch (DataRouterException ex) {
+      logger.info(QueryMsgs.QUERY_ERROR,
+          "Error while calling Chameleon service URL: " + chameleonURL + " failure cause: " + result.getFailureCause());
+      throw ex;
     }
 
+    return response;
   }
 
 }
index a120f89..7e63869 100644 (file)
 package org.onap.aai.datarouter.query;
 
 import java.security.InvalidParameterException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
-import org.apache.camel.Exchange;
-import org.onap.aai.rest.RestClientEndpoint;
+import javax.annotation.PostConstruct;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response.Status;
+
+import org.eclipse.jetty.util.security.Password;
 import org.onap.aai.cl.api.Logger;
 import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.datarouter.exception.DataRouterException;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.aai.restclient.rest.HttpUtil;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
 
-public class ChampRouter extends QueryRouter {
+@Component
+@Qualifier("champ")
+public class ChampRouter implements QueryRouter {
   Logger logger = LoggerFactory.getInstance().getLogger(ChampRouter.class.getName());
 
   private String champBaseURL;
+
+  private RestClient restClient ;
   
+  public ChampRouter(){}
+
+  public ChampRouter(String champBaseURL, RestClientConfig config) {   
+    this.champBaseURL = champBaseURL;
+    this.restClient = new RestClient().validateServerHostname(false).validateServerCertChain(true)
+        .clientCertFile(config.getCertPath())
+        .clientCertPassword(Password.deobfuscate(config.getCertPassword()))
+        .trustStore(config.getTrustStorePath())
+        .connectTimeoutMs(config.getConnectionTimeout())
+        .readTimeoutMs(config.getReadTimeout());
+    validate();
+  }
 
-  public ChampRouter(String champBaseURL) {
-    String baseURL = champBaseURL.endsWith("/") ? champBaseURL.substring(0, champBaseURL.length() - 1)
-        : champBaseURL;
-    if(checkRecursion(baseURL)){
-      logger.info(QueryMsgs.QUERY_INFO, "Invalid champBaseURL : Can't re-route back to DataRouter "+ champBaseURL);
-      throw new InvalidParameterException("Invalid champBaseURL : Can't re-route back to DataRouter "+ champBaseURL);
+  public void validate(){
+    String baseURL = champBaseURL.endsWith("/") ? champBaseURL.substring(0, champBaseURL.length() - 1) : champBaseURL;
+    if (baseURL.contains(DATA_ROUTER_PORT)) {
+      logger.info(QueryMsgs.QUERY_INFO, "Invalid champBaseURL : Can't re-route back to DataRouter " + champBaseURL);
+      throw new InvalidParameterException("Invalid champBaseURL : Can't re-route back to DataRouter " + champBaseURL);
     }
-    this.champBaseURL = baseURL;    
+    this.champBaseURL = baseURL;
   }
 
-  public void setQueryRequest(Exchange exchange) {
-    setMDC(exchange);
-    String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
-    String queryParams = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
-    String ecompUrl;
+  @Override
+  public String process(String urlContext, String queryParams, Map<String, List<String>> headers)
+      throws DataRouterException {
+    String champURL;
+    String response;
     if (queryParams != null && !queryParams.isEmpty()) {
-      ecompUrl = champBaseURL + path + "?" + queryParams;
+      champURL = champBaseURL + urlContext + "?" + queryParams;
     } else {
-      ecompUrl = champBaseURL + path;
+      champURL = champBaseURL + urlContext;
     }
 
-    logger.info(QueryMsgs.QUERY_INFO, "Routing request to Champ service URL: " + ecompUrl);
-    exchange.getIn().setHeader(RestClientEndpoint.IN_HEADER_URL, ecompUrl);
-    exchange.getIn().setHeader("X-FromAppId", SERVICE_NAME);
-    exchange.getIn().setHeader("X-TransactionId", getTxId(exchange));
+    logger.info(QueryMsgs.QUERY_INFO, "Routing request to Champ service URL: " + champURL);
 
-  }
+    headers = headers == null ? new HashMap<String, List<String>>() : headers;
+    headers.put("X-FromAppId", Arrays.asList(DataRouterConstants.DATA_ROUTER_SERVICE_NAME));
+    OperationResult result = restClient.get(champURL, headers, MediaType.APPLICATION_JSON_TYPE);
+
+    if (HttpUtil.isHttpResponseClassSuccess(result.getResultCode())) {
+      response = result.getResult();
+    } else {
+      logger.info(QueryMsgs.QUERY_ERROR,
+          "Error while calling Champ service URL: " + champURL + " failure cause: " + result.getFailureCause());
+      throw new DataRouterException(
+          "Error while calling Champ service URL: " + champURL + " failure cause: " + result.getFailureCause(),
+          Status.fromStatusCode(result.getResultCode()));
+    }
 
-  public void setQueryResponse(Exchange exchange) {
-    Integer httpResponseCode = exchange.getIn().getHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_CODE, Integer.class);
-    // Object httpBody = exchange.getIn().getBody();
-    exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
+    return response;
 
   }
 
index aabeac2..07b4e79 100644 (file)
  */
 package org.onap.aai.datarouter.query;
 
+import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
-import org.apache.camel.Exchange;
 import org.onap.aai.cl.api.Logger;
 import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.datarouter.exception.DataRouterException;
 
-
-public abstract class QueryRouter {
+public interface QueryRouter {
   Logger logger = LoggerFactory.getInstance().getLogger(QueryRouter.class.getName());
 
 
-  protected static final String SERVICE_NAME = "DATA-ROUTER";
-  /** HTTP header containing the ECOMP Request Id */
-  protected static final String HEADER_TRANS_ID = "X-TransactionId";
-  
-  /** HTTP header containing the calling application Id */
-  protected static final String HEADER_FROM_APP_ID = "X-FromAppId";
-  
-  /** HTTP header containing the calling host details */
-  protected static final String HEADER_FROM_HOST = "Host";
-  
-  /** HTTP header containing the calling host details */
-  protected static final String DATA_ROUTER_PORT = "9502";
-  
 
-  public abstract void setQueryRequest(Exchange exchange) ;
-  
-  public abstract void setQueryResponse(Exchange exchange);
-  
-  protected String getTxId(final Exchange exchange){
-    String txId = exchange.getIn().getHeader("X-TransactionId",String.class);    
-    return ((txId==null||txId.isEmpty())?UUID.randomUUID().toString():txId);
-  }
-  
-  protected boolean checkRecursion(String url){
-   return url.contains(DATA_ROUTER_PORT);
-  }
-  
-  protected void setMDC(final Exchange exchange) {
-    String transId = exchange.getIn().getHeader(HEADER_TRANS_ID, String.class);
-    String appId = exchange.getIn().getHeader(HEADER_FROM_APP_ID, String.class);
-    String hostId = exchange.getIn().getHeader(HEADER_FROM_HOST, String.class);
+  /** HTTP header containing the calling host details */
+  static final String DATA_ROUTER_PORT = "9502";
 
-    // Set MDC transaction id, calling service name, calling service id,
-    // partner name, client address
-    MdcContext.initialize(transId, "DataRouter", "", appId, hostId);
-  }
+  public String process(String urlContext, String queryParams, Map<String, List<String>> headers)
+      throws DataRouterException;
 
 }
diff --git a/src/main/java/org/onap/aai/datarouter/query/RestClientConfig.java b/src/main/java/org/onap/aai/datarouter/query/RestClientConfig.java
new file mode 100644 (file)
index 0000000..96a61ba
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.query;
+
+public class RestClientConfig {
+
+  private String certPath;
+  private String certPassword;
+  private String trustStorePath;
+  private String connectionTimeout;
+  private String readTimeout;
+
+  public String getCertPath() {
+    return certPath;
+  }
+
+  public void setCertPath(String certPath) {
+    this.certPath = certPath;
+  }
+
+  public String getCertPassword() {
+    return certPassword;
+  }
+
+  public void setCertPassword(String certPassword) {
+    this.certPassword = certPassword;
+  }
+
+  public String getTrustStorePath() {
+    return trustStorePath;
+  }
+
+  public void setTrustStorePath(String trustStorePath) {
+    this.trustStorePath = trustStorePath;
+  }
+
+  public int getConnectionTimeout() {
+    return parseInt(connectionTimeout,10000);
+  }
+
+  public void setConnectionTimeout(String connectionTimeout) {
+    this.connectionTimeout = connectionTimeout;
+  }
+
+  public int getReadTimeout() {
+    return parseInt(connectionTimeout,10000);
+  }
+
+  public void setReadTimeout(String readTimeout) {
+    this.readTimeout = readTimeout;
+  }
+
+  
+  private int parseInt(String config, int defaultValue) {
+    int intVal = defaultValue; // Default delay of half a sec
+    try {
+      intVal = Integer.parseInt(config);
+    } catch (Exception e) {
+      // Ignore the parsing error and use the default
+    }
+    return intVal;
+  }
+  @Override
+  public String toString() {
+    return "RestClientConfig [certPath=" + certPath + ", certPassword=" + certPassword + ", trustStorePath="
+        + trustStorePath + ", connectionTimeout=" + connectionTimeout + ", readTimeout=" + readTimeout + "]";
+  }
+
+}
index 8192935..70bc129 100644 (file)
  */
 package org.onap.aai.datarouter.service;
 
-import org.onap.aai.cl.api.LogFields;
-import org.onap.aai.cl.api.LogLine;
-import org.onap.aai.cl.api.Logger;
-import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.cl.mdc.MdcContext;
-import org.onap.aai.datarouter.logging.DataRouterMsgs;
-import org.onap.aai.datarouter.util.DataRouterConstants;
-import org.slf4j.MDC;
-
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.GET;
 import javax.ws.rs.Path;
@@ -39,6 +30,18 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 
+import org.onap.aai.cl.api.LogFields;
+import org.onap.aai.cl.api.LogLine;
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.cl.mdc.MdcContext;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.util.DataRouterConstants;
+import org.slf4j.MDC;
+import org.springframework.stereotype.Component;
+
+@Component
+@Path("/data-router/v1")
 public class EchoService {
 
   private static Logger logger = LoggerFactory.getInstance().getLogger(EchoService.class.getName());
@@ -48,7 +51,7 @@ public class EchoService {
   private static final String XTRANSACTIONID = "X-TransactionId";
 
   @GET
-  @Path("echo/{input}")
+  @Path("/echo/{input}")
   @Produces("text/plain")
   public String ping(@PathParam("input") String input, @Context HttpHeaders headers,
       @Context UriInfo info, @Context HttpServletRequest req) {
diff --git a/src/main/java/org/onap/aai/datarouter/service/HistoricalQueryService.java b/src/main/java/org/onap/aai/datarouter/service/HistoricalQueryService.java
new file mode 100644 (file)
index 0000000..2b401b0
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Encoded;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+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 javax.ws.rs.core.UriInfo;
+
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.datarouter.exception.DataRouterException;
+import org.onap.aai.datarouter.logging.DataRouterMsgs;
+import org.onap.aai.datarouter.logging.LoggingUtil;
+import org.onap.aai.datarouter.query.QueryRouter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+@Component
+@Path("/services/champ-service/v1")
+public class HistoricalQueryService {
+
+  private Logger logger = LoggerFactory.getInstance().getLogger(HistoricalQueryService.class);
+  Logger auditLogger = LoggerFactory.getInstance().getAuditLogger(HistoricalQueryService.class.getName());
+  private static Logger metricsLogger = LoggerFactory.getInstance()
+      .getMetricsLogger(HistoricalQueryService.class.getName());
+
+  @Autowired
+  @Qualifier("champ")
+  private QueryRouter champRouter;
+
+  @Autowired
+  @Qualifier("chameleon")
+  private QueryRouter chameleonRouter;
+
+  @GET  
+  @Path("{uri: .+}")
+  @Produces({ MediaType.APPLICATION_JSON })
+  public Response process(String content, @PathParam("version") String versionParam,
+      @PathParam("uri") @Encoded String uri, @Context HttpHeaders httpHeaders, @Context UriInfo uriInfo,
+      @Context HttpServletRequest req) {
+    LoggingUtil.initMdcContext(req, httpHeaders);
+    long startTimeInMs = System.currentTimeMillis();
+    Response response = null;
+    String urlContext = "/"+ uri;
+    String queryParams = uriInfo.getRequestUri().getQuery();
+
+    try {
+
+      Map<String, List<String>> parameters = new HashMap<String, List<String>>();
+      for (Map.Entry<String, List<String>> e : httpHeaders.getRequestHeaders().entrySet()) {
+        parameters.put(e.getKey(), e.getValue());
+      }
+      if (uriInfo.getQueryParameters().containsKey("t-k")) {
+        response = Response.status(Status.OK).entity(chameleonRouter.process(urlContext, queryParams, parameters))
+            .build();
+      } else {
+        response = Response.status(Status.OK).entity(champRouter.process(urlContext, queryParams, parameters)).build();
+      }
+    } catch (DataRouterException ex) {
+      response = Response.status(ex.getHttpStatus()).entity(ex.getMessage()).build();
+
+    } catch (Exception e) {
+      response = Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
+
+    } finally {      
+      LoggingUtil.logRestRequest(logger, auditLogger, req, response);
+      metricsLogger.info(DataRouterMsgs.PROCESSED_REQUEST, "GET",
+          Long.toString(System.currentTimeMillis() - startTimeInMs));
+    }
+    return response;
+
+  }
+
+}
index 74a378f..6233e5c 100644 (file)
@@ -1 +1,14 @@
-camel.springboot.xmlRoutes = file:${DYNAMIC_ROUTES}/*.route
\ No newline at end of file
+camel.springboot.xmlRoutes = file:${DYNAMIC_ROUTES}/*.route
+server.ssl.key-store=file:${CONFIG_HOME}/auth/tomcat_keystore
+
+server.ssl.enabled=true
+server.port=9502
+server.ssl.client-auth=want
+
+server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
+#server.ssl.key-store=client-cert-onap.p12
+#server.ssl.key-store-password=onapSecret
+#server.ssl.trust-store=C:\\ONAP\\spring\\data-router\\dynamic\\tomcat_keystore
+#server.ssl.trust-store-password=onapSecret
+#server.ssl.client-auth=want
+server.ssl.key-store-type=JKS
\ No newline at end of file
index fff262c..6267321 100644 (file)
@@ -170,4 +170,7 @@ FAIL_TO_CREATE_UPDATE_DOC=\
                    Failed to create or update document in index {0}.  Cause: {1}
 LOAD_OXM_ERROR=\
             DR5000E|\
-            Unable to load Oxm model: {0}\                 
+            Unable to load Oxm model: {0}\     
+PROCESSED_REQUEST=\
+  DR00015I|\
+  Processed DataRouter {0} request in {1} ms                       
diff --git a/src/test/java/org/onap/aai/datarouter/query/ChameleonRouterTest.java b/src/test/java/org/onap/aai/datarouter/query/ChameleonRouterTest.java
new file mode 100644 (file)
index 0000000..27c2606
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.query;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.gson.JsonParser;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ ChameleonRouter.class, RestClient.class })
+public class ChameleonRouterTest {
+
+  ChameleonRouter chameleonRouter;
+  RestClient mockRestClient = mock(RestClient.class);
+
+  JsonParser parser = new JsonParser();
+
+  @SuppressWarnings("unchecked")
+  @Before
+  public void init() throws Exception {
+    RestClientConfig config = PowerMockito.mock(RestClientConfig.class);
+    PowerMockito.when(config.getCertPassword()).thenReturn("password");
+
+    PowerMockito.whenNew(RestClient.class).withAnyArguments().thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.validateServerHostname(any(Boolean.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.validateServerCertChain(any(Boolean.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.clientCertFile(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.clientCertPassword(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.trustStore(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.connectTimeoutMs(any(Integer.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.readTimeoutMs(any(Integer.class))).thenReturn(mockRestClient);
+
+    chameleonRouter = new ChameleonRouter("http:///test", config);
+  }
+
+  @Test
+  public void testProcess() throws Exception {
+    OperationResult chameleonResponse = buildChameleonResponse();
+    PowerMockito.when(mockRestClient.get(any(String.class), any(HashMap.class), any(MediaType.class)))
+        .thenReturn(chameleonResponse);
+
+    String chameleonRouterResponse = chameleonRouter.process("/objects/364d646e-c947-4010-a66a-adf06aa306fb", "", null);
+    Assert.assertEquals(parser.parse(chameleonRouterResponse), parser.parse(readSampleChampResponse()));
+
+  }
+
+  private OperationResult buildChameleonResponse() throws IOException {
+    OperationResult response = new OperationResult();
+    response.setResultCode(200);
+
+    response.setResult(readSampleChameleonResponse());
+    return response;
+  }
+
+  private String readSampleChampResponse() throws IOException {
+    FileInputStream event = new FileInputStream(new File("src/test/resources/champ-response.json"));
+    String json = IOUtils.toString(event, "UTF-8");
+    return json;
+  }
+
+  private String readSampleChameleonResponse() throws IOException {
+    FileInputStream event = new FileInputStream(new File("src/test/resources/chameleon-response.json"));
+    String json = IOUtils.toString(event, "UTF-8");
+    return json;
+  }
+
+}
diff --git a/src/test/java/org/onap/aai/datarouter/query/ChampRouterTest.java b/src/test/java/org/onap/aai/datarouter/query/ChampRouterTest.java
new file mode 100644 (file)
index 0000000..1bf7c88
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ================================================================================
+ * 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.datarouter.query;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+
+import javax.ws.rs.core.MediaType;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ ChampRouter.class, RestClient.class })
+public class ChampRouterTest {
+
+  ChampRouter champRouter;
+  RestClient mockRestClient = mock(RestClient.class);
+
+  @SuppressWarnings("unchecked")
+  @Before
+  public void init() throws Exception {
+    RestClientConfig config = PowerMockito.mock(RestClientConfig.class);
+    PowerMockito.when(config.getCertPassword()).thenReturn("password");
+
+    PowerMockito.whenNew(RestClient.class).withAnyArguments().thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.validateServerHostname(any(Boolean.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.validateServerCertChain(any(Boolean.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.clientCertFile(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.clientCertPassword(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.trustStore(any(String.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.connectTimeoutMs(any(Integer.class))).thenReturn(mockRestClient);
+    PowerMockito.when(mockRestClient.readTimeoutMs(any(Integer.class))).thenReturn(mockRestClient);
+
+    champRouter = new ChampRouter("http:///test", config);
+  }
+
+  @Test
+  public void testProcess() throws Exception {
+    OperationResult champResponse = buildChampResponse();
+    PowerMockito.when(mockRestClient.get(any(String.class), any(HashMap.class), any(MediaType.class)))
+        .thenReturn(champResponse);
+
+    String champRouterResponse = champRouter.process("/object/1234", "", null);
+    Assert.assertEquals(champRouterResponse, readSampleChampResponse());
+
+  }
+
+  private OperationResult buildChampResponse() throws IOException {
+    OperationResult response = new OperationResult();
+    response.setResultCode(200);
+
+    response.setResult(readSampleChampResponse());
+    return response;
+  }
+
+  private String readSampleChampResponse() throws IOException {
+    FileInputStream event = new FileInputStream(new File("src/test/resources/champ-response.json"));
+    String json = IOUtils.toString(event, "UTF-8");
+    return json;
+  }
+
+}
diff --git a/src/test/resources/chameleon-response.json b/src/test/resources/chameleon-response.json
new file mode 100644 (file)
index 0000000..056bd46
--- /dev/null
@@ -0,0 +1,13 @@
+{
+      "ptnii-equip-name": "mtanj119snd-updated-now",      
+      "equip-type": "phone",
+      "equip-vendor": "Samsung",
+      "fqdn": "mtanjrsv119.mtanj.sbcglobal.net",
+      "purpose": "",     
+      "ipv4-oam-address": "135.182.138.60",      
+      "hostname": "phonehost",
+      "equip-model": "DL380p-nd",
+      "aai-uuid": "364d646e-c947-4010-a66a-adf06aa306fb",
+      "resource-version": "1477013499",
+      "type": "pserver"
+}
\ No newline at end of file
diff --git a/src/test/resources/champ-response.json b/src/test/resources/champ-response.json
new file mode 100644 (file)
index 0000000..105f408
--- /dev/null
@@ -0,0 +1,16 @@
+{
+   "key": "364d646e-c947-4010-a66a-adf06aa306fb",
+   "type": "pserver",
+   "properties":    {
+      "ptnii-equip-name": "mtanj119snd-updated-now",      
+      "equip-type": "phone",
+      "equip-vendor": "Samsung",
+      "fqdn": "mtanjrsv119.mtanj.sbcglobal.net",
+      "purpose": "",      
+      "ipv4-oam-address": "135.182.138.60",      
+      "hostname": "phonehost",
+      "equip-model": "DL380p-nd",
+      "aai-uuid": "364d646e-c947-4010-a66a-adf06aa306fb",
+      "resource-version": "1477013499"
+   }
+}
\ No newline at end of file