aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--netconfsimulator/Dockerfile_netopeer2
-rw-r--r--pnfsimulator/Dockerfile1
-rw-r--r--pnfsimulator/README.md19
-rw-r--r--pnfsimulator/docker-compose.yml2
-rw-r--r--pnfsimulator/integration/src/main/java/org/onap/pnfsimulator/integration/VesSimulatorController.java28
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java10
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/OptionalTemplatesTest.java67
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/SingleEventTest.java151
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/TestUtils.java57
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/VariablesReplacement.java8
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/suites/DockerBasedTestsSuite.java3
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java63
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java5
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactory.java45
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java3
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java40
-rw-r--r--pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpResponseAdapter.java41
-rw-r--r--pnfsimulator/src/main/resources/application.properties4
-rw-r--r--pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java3
-rw-r--r--pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java31
-rw-r--r--pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactoryTest.java98
-rw-r--r--pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java67
-rw-r--r--pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpTestUtils.java55
23 files changed, 662 insertions, 141 deletions
diff --git a/netconfsimulator/Dockerfile_netopeer b/netconfsimulator/Dockerfile_netopeer
index 4d15392..ad8db7c 100644
--- a/netconfsimulator/Dockerfile_netopeer
+++ b/netconfsimulator/Dockerfile_netopeer
@@ -1,4 +1,4 @@
-FROM docker.io/sysrepo/sysrepo-netopeer2:legacy
+FROM docker.io/sysrepo/sysrepo-netopeer2:v0.7.7
ADD apt.conf /etc/apt/apt.conf
RUN apt-get update && apt-get install -y python3 python3-pip python-pip && pip3 install flask flask_restful kafka-python && pip install kafka-python
RUN cd /opt/dev/sysrepo && cmake -DGEN_PYTHON_VERSION=2 -DREPOSITORY_LOC:PATH=/etc/sysrepo . && make install
diff --git a/pnfsimulator/Dockerfile b/pnfsimulator/Dockerfile
index e53824e..2cd3d9d 100644
--- a/pnfsimulator/Dockerfile
+++ b/pnfsimulator/Dockerfile
@@ -14,4 +14,5 @@ RUN python -m pip install -r /opt/db/config/requirements.txt
ADD certificates /usr/local/share/ca-certificates/
RUN update-ca-certificates
CMD python /opt/db/config/mongo_db_schema_creation.py \
+ && if [ -f /app/store/trust.pass ]; then cp /app/store/trust.pass /app/store/truststore.pass; fi \
&& java -Dspring.config.location=file:/app/application.properties -cp /app/libs/*:/app/pnf-simulator.jar org.onap.pnfsimulator.Main \
diff --git a/pnfsimulator/README.md b/pnfsimulator/README.md
index 9f7e996..844fdf5 100644
--- a/pnfsimulator/README.md
+++ b/pnfsimulator/README.md
@@ -56,7 +56,12 @@ Sample Request:
Enables direct, immediate event sending without need to have template deployed on backend.
Keywords are supported,thus once passed, will also be substituted with proper strings.
Passed event body must be valid and complete event according to VES Collector interface.
-To trigger sending use following endpoint *http://<simulator_ip>:5000/simulator/event*.
+To trigger sending use following endpoint *http://<simulator_ip>:5000/simulator/event*.
+After sending event, response message from VES will be passed as response message from Simulator.
+Thanks to that when sending one-time event user will receive information about request.
+This is helpful when authentication fail or VES response with "Forbidden" when using http instead of https.
+In a situation when given URL address is not pointing to VES, Simulator response with status ```421```
+and information about communication problem.
Supported method: *POST*
Headers:
@@ -108,7 +113,7 @@ The simulator provides means for managing templates. Supported actions: adding,
```GET /template/list```
Lists all templates known to the simulator.
-```GET /template/get-content/{name}```
+```GET /template/get/{name}```
Gets template content based on *name* path variable.
```POST /template/upload?override=true```
@@ -370,8 +375,14 @@ CA certificates are incorporated into simulator docker image, thus no additional
Certificates can be found in docker container under path: */usr/local/share/ca-certificates/*
-Simulator works with VES that uses both self-signed certificate (already present in keystore) and VES integrated to AAF.
-
+Simulator works with VES that uses both self-signed certificate (already present in keystore) and VES integrated to AAF.
+
+Certification loading can be disabled by setting environment variable ```USE_CERTIFICATE_FOR_AUTHORIZATION``` to false.
+Once certificate are not used for authorization, user can set up VES url using username and password.
+
+ {
+ "vesServerUrl": "http://<user>:<password>@<ves_url>:<port>/eventListener/v7"
+ }
## Developers Guide
diff --git a/pnfsimulator/docker-compose.yml b/pnfsimulator/docker-compose.yml
index 54e4699..c7a19eb 100644
--- a/pnfsimulator/docker-compose.yml
+++ b/pnfsimulator/docker-compose.yml
@@ -27,6 +27,8 @@ services:
image: onap/org.onap.integration.simulators.pnfsimulator
ports:
- "5000:5000"
+ environment:
+ USE_CERTIFICATE_FOR_AUTHORIZATION: "true"
volumes:
- ./logs:/var/log
- ./templates:/app/templates
diff --git a/pnfsimulator/integration/src/main/java/org/onap/pnfsimulator/integration/VesSimulatorController.java b/pnfsimulator/integration/src/main/java/org/onap/pnfsimulator/integration/VesSimulatorController.java
index 70e0c60..304df60 100644
--- a/pnfsimulator/integration/src/main/java/org/onap/pnfsimulator/integration/VesSimulatorController.java
+++ b/pnfsimulator/integration/src/main/java/org/onap/pnfsimulator/integration/VesSimulatorController.java
@@ -22,18 +22,27 @@ package org.onap.pnfsimulator.integration;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+
@RequestMapping("ves-simulator")
@RestController
public class VesSimulatorController {
+ private static final Logger LOGGER = LoggerFactory.getLogger(VesSimulatorController.class);
private final VesSimulatorService vesSimulatorService;
private final Gson gson;
+ private final ResponseEntity<String> response = ResponseEntity
+ .status(HttpStatus.ACCEPTED)
+ .body("Accepted");
@Autowired
public VesSimulatorController(VesSimulatorService vesSimulatorService, Gson gson) {
@@ -42,18 +51,21 @@ public class VesSimulatorController {
}
@PostMapping("eventListener/v5")
- String sendEventToDmaapV5(@RequestBody String body) {
- System.out.println("Received event" + body);
- JsonObject jsonObject = gson.fromJson(body, JsonObject.class);
+ public ResponseEntity<String> sendEventToDmaapV5(@RequestBody String body) {
+ JsonObject jsonObject = getJsonObjectFromBody(body);
vesSimulatorService.sendEventToDmaapV5(jsonObject);
- return "MessageAccepted";
+ return response;
}
@PostMapping("eventListener/v7")
- String sendEventToDmaapV7(@RequestBody String body) {
- System.out.println("Received event" + body);
- JsonObject jsonObject = gson.fromJson(body, JsonObject.class);
+ public ResponseEntity<String> sendEventToDmaapV7(@RequestBody String body) {
+ JsonObject jsonObject = getJsonObjectFromBody(body);
vesSimulatorService.sendEventToDmaapV7(jsonObject);
- return "MessageAccepted";
+ return response;
+ }
+
+ private JsonObject getJsonObjectFromBody(@RequestBody String body) {
+ LOGGER.info(String.format("Received event: %s", body));
+ return gson.fromJson(body, JsonObject.class);
}
}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java
index fffc447..323243c 100644
--- a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java
@@ -24,6 +24,7 @@ import static io.restassured.RestAssured.given;
import static io.restassured.RestAssured.when;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import static org.onap.pnfsimulator.integration.TestUtils.getCurrentIpAddress;
import com.google.gson.JsonObject;
@@ -230,13 +231,4 @@ public class BasicAvailabilityTest {
return "http://0.0.0.0:5000/simulator/" + action;
}
- private String getCurrentIpAddress() throws SocketException {
- return Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
- .flatMap(i -> Collections.list(i.getInetAddresses()).stream())
- .filter(ip -> ip instanceof Inet4Address)
- .map(e -> (Inet4Address) e)
- .findFirst()
- .orElseThrow(RuntimeException::new)
- .getHostAddress();
- }
}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/OptionalTemplatesTest.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/OptionalTemplatesTest.java
index a5ffe4d..50ad1cd 100644
--- a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/OptionalTemplatesTest.java
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/OptionalTemplatesTest.java
@@ -23,22 +23,16 @@ package org.onap.pnfsimulator.integration;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import static org.onap.pnfsimulator.integration.TestUtils.COMMON_EVENT_HEADER;
+import static org.onap.pnfsimulator.integration.TestUtils.PATCHED;
+import static org.onap.pnfsimulator.integration.TestUtils.SINGLE_EVENT_URL;
+import static org.onap.pnfsimulator.integration.TestUtils.findSourceNameInMongoDB;
+import static org.onap.pnfsimulator.integration.TestUtils.getCurrentIpAddress;
import com.google.gson.JsonObject;
-import com.mongodb.MongoClient;
-import com.mongodb.MongoClientOptions;
-import com.mongodb.MongoCredential;
-import com.mongodb.ServerAddress;
-import com.mongodb.client.FindIterable;
-import com.mongodb.client.MongoCollection;
-import com.mongodb.client.MongoCursor;
-import com.mongodb.client.MongoDatabase;
import java.time.Instant;
-import java.net.Inet4Address;
-import java.net.NetworkInterface;
-import java.net.SocketException;
import java.net.UnknownHostException;
-import java.util.Collections;
+
import org.assertj.core.api.Assertions;
import org.bson.Document;
import org.junit.After;
@@ -50,22 +44,13 @@ import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.http.HttpStatus;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Main.class, TestConfiguration.class}, webEnvironment = WebEnvironment.DEFINED_PORT)
public class OptionalTemplatesTest {
- private static final String PNF_SIMULATOR_DB = "pnf_simulator";
- private static final String COMMON_EVENT_HEADER = "commonEventHeader";
- private static final String PNF_SIMULATOR_DB_PSWD = "zXcVbN123!";
- private static final String PNF_SIMULATOR_DB_USER = "pnf_simulator_user";
- private static final String PATCHED = "patched";
- private static final String SINGLE_EVENT_URL = "http://0.0.0.0:5000/simulator/event";
-
- @Autowired
- VesSimulatorController vesSimulatorController;
-
@Autowired
private VesSimulatorService vesSimulatorService;
@@ -109,8 +94,8 @@ public class OptionalTemplatesTest {
.when()
.post(SINGLE_EVENT_URL)
.then()
- .statusCode(202)
- .body("message", equalTo("One-time direct event sent successfully"));
+ .statusCode(HttpStatus.ACCEPTED.value())
+ .body("message", equalTo("Accepted"));
//then
long afterExecution = Instant.now().getEpochSecond();
@@ -124,7 +109,7 @@ public class OptionalTemplatesTest {
.get("sourceName").getAsString()).isEqualTo("Single_sourceName");
assertThat(value
.getAsJsonObject(COMMON_EVENT_HEADER)
- .get("eventId1").getAsString().length()).isEqualTo(20);
+ .get("eventId1").getAsString()).hasSize(20);
assertThat(value
.getAsJsonObject(COMMON_EVENT_HEADER)
.get("eventId2").getAsString()).isEqualTo("10");
@@ -160,8 +145,8 @@ public class OptionalTemplatesTest {
.when()
.post(SINGLE_EVENT_URL)
.then()
- .statusCode(202)
- .body("message", equalTo("One-time direct event sent successfully"));
+ .statusCode(HttpStatus.ACCEPTED.value())
+ .body("message", equalTo("Accepted"));
//then
Mockito.verify(vesSimulatorService,
@@ -173,32 +158,4 @@ public class OptionalTemplatesTest {
.isEqualTo("{\"commonEventHeader\":{\"sourceName\":\"HistoricalEvent\",\"version\":3}}");
}
- private Document findSourceNameInMongoDB() throws UnknownHostException {
- MongoCredential credential = MongoCredential
- .createCredential(PNF_SIMULATOR_DB_USER, PNF_SIMULATOR_DB, PNF_SIMULATOR_DB_PSWD.toCharArray());
- MongoClient mongoClient = new MongoClient(new ServerAddress(Inet4Address.getLocalHost(), 27017),
- credential, MongoClientOptions.builder().build());
- MongoDatabase pnfSimulatorDb = mongoClient.getDatabase(PNF_SIMULATOR_DB);
- MongoCollection<Document> table = pnfSimulatorDb.getCollection("eventData");
- Document searchQuery = new Document();
- searchQuery.put(PATCHED, new Document("$regex", ".*" + "HistoricalEvent" + ".*"));
- FindIterable<Document> findOfPatched = table.find(searchQuery);
- Document dbObject = null;
- MongoCursor<Document> cursor = findOfPatched.iterator();
- if (cursor.hasNext()) {
- dbObject = cursor.next();
- }
- return dbObject;
- }
-
- private String getCurrentIpAddress() throws SocketException {
- return Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
- .flatMap(i -> Collections.list(i.getInetAddresses()).stream())
- .filter(ip -> ip instanceof Inet4Address)
- .map(e -> (Inet4Address) e)
- .findFirst()
- .orElseThrow(RuntimeException::new)
- .getHostAddress();
- }
-
}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/SingleEventTest.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/SingleEventTest.java
new file mode 100644
index 0000000..3ad1385
--- /dev/null
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/SingleEventTest.java
@@ -0,0 +1,151 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Simulator
+ * ================================================================================
+ * Copyright (C) 2020 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.pnfsimulator.integration;
+
+import com.google.gson.JsonObject;
+import org.assertj.core.api.Assertions;
+import org.bson.Document;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.net.UnknownHostException;
+import java.util.List;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.stringContainsInOrder;
+import static org.onap.pnfsimulator.integration.TestUtils.PATCHED;
+import static org.onap.pnfsimulator.integration.TestUtils.SINGLE_EVENT_URL;
+import static org.onap.pnfsimulator.integration.TestUtils.findSourceNameInMongoDB;
+import static org.onap.pnfsimulator.integration.TestUtils.getCurrentIpAddress;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = {Main.class, TestConfiguration.class}, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
+public class SingleEventTest {
+
+ @Autowired
+ private VesSimulatorService vesSimulatorService;
+
+ private String currentVesSimulatorIp;
+
+ @Before
+ public void setUp() throws Exception {
+ currentVesSimulatorIp = getCurrentIpAddress();
+ }
+
+ @After
+ public void tearDown() {
+ Mockito.reset(vesSimulatorService);
+ }
+
+ @Test
+ public void whenTriggeredSimulatorWithWrongVesAddressInformationShouldBeReturned() {
+ //given
+ String body = "{\n"
+ + "\"vesServerUrl\": \"https://" + currentVesSimulatorIp + ":8080/ves-simulator/eventListener/v5\",\n"
+ + "\"event\": { \n"
+ + "\"commonEventHeader\": {\n"
+ + "\"sourceName\": \"HistoricalEvent\",\n"
+ + "\"version\": 3"
+ + "}\n"
+ + "}\n"
+ + "}";
+
+ //when
+ given()
+ .contentType("application/json")
+ .body(body)
+ .when()
+ .post(SINGLE_EVENT_URL)
+ .then()
+ .statusCode(421)
+ .body("message",
+ equalTo(
+ "Fail to connect with ves: Connect to "+currentVesSimulatorIp+":8080 " +
+ "[/"+currentVesSimulatorIp+"] " +
+ "failed: Connection refused (Connection refused)"));
+ }
+
+ @Test
+ public void whenTriggeredSimulatorWithWrongEventShouldReturnedError() {
+ //given
+ String body = "{\n"
+ + "\"vesServerUrl\": \"https://" + currentVesSimulatorIp + ":9443/ves-simulator/eventListener/v5\",\n"
+ + "\"event\": { \n"
+ + "this is not JSON {}"
+ + "}\n"
+ + "}";
+
+ //when
+ given()
+ .contentType("application/json")
+ .body(body)
+ .when()
+ .post(SINGLE_EVENT_URL)
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST.value())
+ .body("message",
+ stringContainsInOrder(List.of("JSON parse error:","Unexpected character ('t' (code 116)):"))
+ );
+ }
+
+ @Test
+ public void whenTriggeredSimulatorWithUsernameAndPasswordInUrlVesShouldAcceptRequest() throws UnknownHostException {
+ //given
+ String body = "{\n"
+ + "\"vesServerUrl\": \"https://user1:pass1@" + currentVesSimulatorIp + ":9443/ves-simulator/eventListener/v5\",\n"
+ + "\"event\": { \n"
+ + "\"commonEventHeader\": {\n"
+ + "\"sourceName\": \"HistoricalEvent\",\n"
+ + "\"version\": 3"
+ + "}\n"
+ + "}\n"
+ + "}";
+ ArgumentCaptor<JsonObject> parameterCaptor = ArgumentCaptor.forClass(JsonObject.class);
+
+ //when
+ given()
+ .contentType("application/json")
+ .body(body)
+ .when()
+ .post(SINGLE_EVENT_URL)
+ .then()
+ .statusCode(HttpStatus.ACCEPTED.value())
+ .body("message", equalTo("Accepted"));
+
+ //then
+ Mockito.verify(vesSimulatorService,
+ Mockito.timeout(3000))
+ .sendEventToDmaapV5(parameterCaptor.capture());
+
+ Document sourceNameInMongoDB = findSourceNameInMongoDB();
+ Assertions.assertThat(sourceNameInMongoDB.get(PATCHED))
+ .isEqualTo("{\"commonEventHeader\":{\"sourceName\":\"HistoricalEvent\",\"version\":3}}");
+ }
+}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/TestUtils.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/TestUtils.java
new file mode 100644
index 0000000..f7df5e9
--- /dev/null
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/TestUtils.java
@@ -0,0 +1,57 @@
+package org.onap.pnfsimulator.integration;
+
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientOptions;
+import com.mongodb.MongoCredential;
+import com.mongodb.ServerAddress;
+import com.mongodb.client.FindIterable;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoCursor;
+import com.mongodb.client.MongoDatabase;
+import org.bson.Document;
+
+import java.net.Inet4Address;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.Collections;
+
+public class TestUtils {
+
+ private TestUtils() {}
+
+ public static final String PNF_SIMULATOR_DB = "pnf_simulator";
+ public static final String COMMON_EVENT_HEADER = "commonEventHeader";
+ public static final String PNF_SIMULATOR_DB_PSWD = "zXcVbN123!";
+ public static final String PNF_SIMULATOR_DB_USER = "pnf_simulator_user";
+ public static final String PATCHED = "patched";
+ public static final String SINGLE_EVENT_URL = "http://0.0.0.0:5000/simulator/event";
+
+ public static Document findSourceNameInMongoDB() throws UnknownHostException {
+ MongoCredential credential = MongoCredential
+ .createCredential(PNF_SIMULATOR_DB_USER, PNF_SIMULATOR_DB, PNF_SIMULATOR_DB_PSWD.toCharArray());
+ MongoClient mongoClient = new MongoClient(new ServerAddress(Inet4Address.getLocalHost(), 27017),
+ credential, MongoClientOptions.builder().build());
+ MongoDatabase pnfSimulatorDb = mongoClient.getDatabase(PNF_SIMULATOR_DB);
+ MongoCollection<Document> table = pnfSimulatorDb.getCollection("eventData");
+ Document searchQuery = new Document();
+ searchQuery.put(PATCHED, new Document("$regex", ".*" + "HistoricalEvent" + ".*"));
+ FindIterable<Document> findOfPatched = table.find(searchQuery);
+ Document dbObject = null;
+ MongoCursor<Document> cursor = findOfPatched.iterator();
+ if (cursor.hasNext()) {
+ dbObject = cursor.next();
+ }
+ return dbObject;
+ }
+
+ public static String getCurrentIpAddress() throws SocketException {
+ return Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
+ .flatMap(i -> Collections.list(i.getInetAddresses()).stream())
+ .filter(ip -> ip instanceof Inet4Address)
+ .map(e -> (Inet4Address) e)
+ .findFirst()
+ .orElseThrow(RuntimeException::new)
+ .getHostAddress();
+ }
+}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/VariablesReplacement.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/VariablesReplacement.java
index c0bd989..ae7970c 100644
--- a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/VariablesReplacement.java
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/VariablesReplacement.java
@@ -3,6 +3,7 @@ package org.onap.pnfsimulator.integration;
import static io.restassured.RestAssured.given;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hamcrest.Matchers.equalTo;
+import static org.onap.pnfsimulator.integration.TestUtils.getCurrentIpAddress;
import com.google.gson.JsonObject;
import java.net.Inet4Address;
@@ -76,11 +77,4 @@ public class VariablesReplacement {
return "http://0.0.0.0:5000/simulator/start";
}
- private String getCurrentIpAddress() throws SocketException {
- return Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
- .flatMap(i -> Collections.list(i.getInetAddresses()).stream())
- .filter(ip -> ip instanceof Inet4Address).map(e -> (Inet4Address) e).findFirst()
- .orElseThrow(RuntimeException::new).getHostAddress();
- }
-
}
diff --git a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/suites/DockerBasedTestsSuite.java b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/suites/DockerBasedTestsSuite.java
index 3de06c3..f6a4c24 100644
--- a/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/suites/DockerBasedTestsSuite.java
+++ b/pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/suites/DockerBasedTestsSuite.java
@@ -30,6 +30,7 @@ import org.junit.runners.Suite.SuiteClasses;
import org.onap.pnfsimulator.integration.BasicAvailabilityTest;
import org.onap.pnfsimulator.integration.OptionalTemplatesTest;
import org.onap.pnfsimulator.integration.SearchInTemplatesTest;
+import org.onap.pnfsimulator.integration.SingleEventTest;
import org.onap.pnfsimulator.integration.TemplatesManagementTest;
import org.onap.pnfsimulator.integration.VariablesReplacement;
import org.slf4j.Logger;
@@ -40,7 +41,7 @@ import static io.restassured.RestAssured.given;
@RunWith(Suite.class)
@SuiteClasses({BasicAvailabilityTest.class, TemplatesManagementTest.class, OptionalTemplatesTest.class,
- SearchInTemplatesTest.class, VariablesReplacement.class})
+ SearchInTemplatesTest.class, VariablesReplacement.class, SingleEventTest.class})
public class DockerBasedTestsSuite {
private static final Logger LOGGER = LoggerFactory.getLogger(DockerBasedTestsSuite.class);
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java
index 023b163..f2c70dd 100644
--- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java
@@ -30,6 +30,7 @@ import org.onap.pnfsimulator.rest.model.SimulatorRequest;
import org.onap.pnfsimulator.rest.util.DateUtil;
import org.onap.pnfsimulator.rest.util.ResponseBuilder;
import org.onap.pnfsimulator.simulator.SimulatorService;
+import org.onap.pnfsimulator.simulator.client.HttpResponseAdapter;
import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig;
import org.quartz.SchedulerException;
import org.slf4j.Logger;
@@ -68,7 +69,6 @@ import static org.onap.pnfsimulator.logging.MdcVariables.X_INVOCATION_ID;
import static org.onap.pnfsimulator.logging.MdcVariables.X_ONAP_REQUEST_ID;
import static org.onap.pnfsimulator.rest.util.ResponseBuilder.MESSAGE;
import static org.onap.pnfsimulator.rest.util.ResponseBuilder.TIMESTAMP;
-import static org.springframework.http.HttpStatus.ACCEPTED;
import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
import static org.springframework.http.HttpStatus.NOT_FOUND;
@@ -99,7 +99,7 @@ public class SimulatorController {
*/
@PostMapping("test")
@Deprecated
- public ResponseEntity<Map<String,Object>> test(@Valid @RequestBody SimulatorRequest simulatorRequest) {
+ public ResponseEntity<Map<String, Object>> test(@Valid @RequestBody SimulatorRequest simulatorRequest) {
MDC.put("test", "test");
String simulatorRequestString = simulatorRequest.toString();
LOGGER.info(ENTRY, simulatorRequestString);
@@ -107,8 +107,8 @@ public class SimulatorController {
}
@PostMapping(value = "start")
- public ResponseEntity<Map<String,Object>> start(@RequestHeader HttpHeaders headers,
- @Valid @RequestBody SimulatorRequest triggerEventRequest) {
+ public ResponseEntity<Map<String, Object>> start(@RequestHeader HttpHeaders headers,
+ @Valid @RequestBody SimulatorRequest triggerEventRequest) {
logContextHeaders(headers, "/simulator/start");
LOGGER.info(ENTRY, "Simulator started");
@@ -120,23 +120,23 @@ public class SimulatorController {
LOGGER.warn("Cannot trigger event, invalid json format: {}", e.getMessage());
LOGGER.debug("Received json has invalid format", e);
return buildResponse(BAD_REQUEST, ImmutableMap.of(MESSAGE, String
- .format(INCORRECT_TEMPLATE_MESSAGE, triggerEventRequest.getTemplateName(),
- e.getMessage())));
+ .format(INCORRECT_TEMPLATE_MESSAGE, triggerEventRequest.getTemplateName(),
+ e.getMessage())));
} catch (GeneralSecurityException e) {
MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
LOGGER.error("Client certificate validation failed: {}", e.getMessage());
return buildResponse(INTERNAL_SERVER_ERROR,
- ImmutableMap.of(MESSAGE, "Invalid or misconfigured client certificate"));
+ ImmutableMap.of(MESSAGE, "Invalid or misconfigured client certificate"));
} catch (IOException e) {
MDC.put(RESPONSE_CODE, BAD_REQUEST.toString());
LOGGER.warn("Json validation failed: {}", e.getMessage());
return buildResponse(BAD_REQUEST,
- ImmutableMap.of(MESSAGE, String.format(NOT_EXISTING_TEMPLATE, triggerEventRequest.getTemplateName())));
+ ImmutableMap.of(MESSAGE, String.format(NOT_EXISTING_TEMPLATE, triggerEventRequest.getTemplateName())));
} catch (Exception e) {
MDC.put(RESPONSE_CODE, INTERNAL_SERVER_ERROR.toString());
LOGGER.error("Cannot trigger event - unexpected exception", e);
return buildResponse(INTERNAL_SERVER_ERROR,
- ImmutableMap.of(MESSAGE, "Unexpected exception: " + e.getMessage()));
+ ImmutableMap.of(MESSAGE, "Unexpected exception: " + e.getMessage()));
} finally {
MDC.clear();
}
@@ -147,30 +147,30 @@ public class SimulatorController {
*/
@GetMapping("all-events")
@Deprecated
- public ResponseEntity<Map<String,Object>> allEvents() {
+ public ResponseEntity<Map<String, Object>> allEvents() {
List<EventData> eventDataList = eventDataService.getAllEvents();
StringBuilder sb = new StringBuilder();
eventDataList.forEach(e -> sb.append(e).append(System.lineSeparator()));
return ResponseBuilder
- .status(OK).put(MESSAGE, sb.toString())
- .build();
+ .status(OK).put(MESSAGE, sb.toString())
+ .build();
}
@GetMapping("config")
- public ResponseEntity<Map<String,Object>> getConfig() {
+ public ResponseEntity<Map<String, Object>> getConfig() {
SimulatorConfig configToGet = simulatorService.getConfiguration();
return buildResponse(OK, ImmutableMap.of("simulatorConfig", configToGet));
}
@PutMapping("config")
- public ResponseEntity<Map<String,Object>> updateConfig(@Valid @RequestBody SimulatorConfig newConfig) {
+ public ResponseEntity<Map<String, Object>> updateConfig(@Valid @RequestBody SimulatorConfig newConfig) {
SimulatorConfig updatedConfig = simulatorService.updateConfiguration(newConfig);
return buildResponse(OK, ImmutableMap.of("simulatorConfig", updatedConfig));
}
@PostMapping("cancel/{jobName}")
- public ResponseEntity<Map<String,Object>> cancelEvent(@PathVariable String jobName) throws SchedulerException {
+ public ResponseEntity<Map<String, Object>> cancelEvent(@PathVariable String jobName) throws SchedulerException {
String jobNameNoBreakingCharacters = replaceBreakingCharacters(jobName);
LOGGER.info(ENTRY, "Cancel called on {}.", jobNameNoBreakingCharacters);
boolean isCancelled = simulatorService.cancelEvent(jobName);
@@ -178,41 +178,52 @@ public class SimulatorController {
}
@PostMapping("cancel")
- public ResponseEntity<Map<String,Object>> cancelAllEvent() throws SchedulerException {
+ public ResponseEntity<Map<String, Object>> cancelAllEvent() throws SchedulerException {
LOGGER.info(ENTRY, "Cancel called on all jobs");
boolean isCancelled = simulatorService.cancelAllEvents();
return createCancelEventResponse(isCancelled);
}
@PostMapping("event")
- public ResponseEntity<Map<String,Object>> sendEventDirectly(@RequestHeader HttpHeaders headers, @Valid @RequestBody FullEvent event)
- throws IOException, GeneralSecurityException {
+ public ResponseEntity<Map<String, Object>> sendEventDirectly(@RequestHeader HttpHeaders headers, @Valid @RequestBody FullEvent event)
+ throws IOException, GeneralSecurityException {
logContextHeaders(headers, "/simulator/event");
LOGGER.info(ENTRY, "Trying to send one-time event directly to VES Collector");
- simulatorService.triggerOneTimeEvent(event);
- return buildResponse(ACCEPTED, ImmutableMap.of(MESSAGE, "One-time direct event sent successfully"));
+ HttpResponseAdapter response = simulatorService.triggerOneTimeEvent(event);
+ return buildResponse(response);
}
private String replaceBreakingCharacters(String jobName) {
return jobName.replaceAll(BREAKING_CHARACTER_REGEX, "_");
}
- private ResponseEntity<Map<String,Object>> processRequest(SimulatorRequest triggerEventRequest)
- throws IOException, SchedulerException, GeneralSecurityException {
+ private ResponseEntity<Map<String, Object>> processRequest(SimulatorRequest triggerEventRequest)
+ throws IOException, SchedulerException, GeneralSecurityException {
String jobName = simulatorService.triggerEvent(triggerEventRequest);
MDC.put(RESPONSE_CODE, OK.toString());
return buildResponse(OK, ImmutableMap.of(MESSAGE, "Request started", "jobName", jobName));
}
- private ResponseEntity<Map<String,Object>> buildResponse(HttpStatus endStatus, Map<String, Object> parameters) {
+ private ResponseEntity<Map<String, Object>> buildResponse(HttpStatus endStatus, Map<String, Object> parameters) {
ResponseBuilder builder = ResponseBuilder
- .status(endStatus)
- .put(TIMESTAMP, DateUtil.getTimestamp(responseDateFormat));
+ .status(endStatus)
+ .put(TIMESTAMP, DateUtil.getTimestamp(responseDateFormat));
parameters.forEach(builder::put);
return builder.build();
}
+ private ResponseEntity<Map<String, Object>> buildResponse(HttpResponseAdapter response) {
+ HttpStatus status = HttpStatus.valueOf(response.getCode());
+ Map<String, Object> parameters;
+ if (response.getMessage().isEmpty()) {
+ parameters = Map.of(MESSAGE, "One-time direct event sent successfully");
+ } else {
+ parameters = Map.of(MESSAGE, response.getMessage());
+ }
+ return buildResponse(status, parameters);
+ }
+
private void logContextHeaders(HttpHeaders headers, String serviceName) {
MDC.put(REQUEST_ID, headers.getFirst(X_ONAP_REQUEST_ID));
MDC.put(INVOCATION_ID, headers.getFirst(X_INVOCATION_ID));
@@ -220,7 +231,7 @@ public class SimulatorController {
MDC.put(SERVICE_NAME, serviceName);
}
- private ResponseEntity<Map<String,Object>> createCancelEventResponse(boolean isCancelled) {
+ private ResponseEntity<Map<String, Object>> createCancelEventResponse(boolean isCancelled) {
if (isCancelled) {
return buildResponse(OK, ImmutableMap.of(MESSAGE, "Event(s) was cancelled"));
} else {
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java
index e5576b8..218dbc8 100644
--- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java
@@ -29,6 +29,7 @@ import org.onap.pnfsimulator.rest.model.SimulatorParams;
import org.onap.pnfsimulator.rest.model.SimulatorRequest;
import org.onap.pnfsimulator.simulator.client.HttpClientAdapter;
import org.onap.pnfsimulator.simulator.client.HttpClientAdapterImpl;
+import org.onap.pnfsimulator.simulator.client.HttpResponseAdapter;
import org.onap.pnfsimulator.simulator.client.utils.ssl.SslAuthenticationHelper;
import org.onap.pnfsimulator.simulator.scheduler.EventScheduler;
import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig;
@@ -93,14 +94,14 @@ public class SimulatorService {
patchedJsonWithVariablesSubstituted);
}
- public void triggerOneTimeEvent(FullEvent event) throws IOException, GeneralSecurityException {
+ public HttpResponseAdapter triggerOneTimeEvent(FullEvent event) throws IOException, GeneralSecurityException {
KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), id -> 1);
JsonObject withKeywordsSubstituted = keywordsHandler.substituteKeywords(event.getEvent(), "").getAsJsonObject();
HttpClientAdapter client = createHttpClientAdapter(event.getVesServerUrl());
eventDataService.persistEventData(EMPTY_JSON_OBJECT, withKeywordsSubstituted, event.getEvent(), EMPTY_JSON_OBJECT);
- client.send(withKeywordsSubstituted.toString());
+ return client.send(withKeywordsSubstituted.toString());
}
public SimulatorConfig getConfiguration() {
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactory.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactory.java
new file mode 100644
index 0000000..36ba922
--- /dev/null
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactory.java
@@ -0,0 +1,45 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.pnfsimulator.simulator.client;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.util.EntityUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+public class HttpApacheResponseAdapterFactory {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(HttpApacheResponseAdapterFactory.class);
+
+ public HttpResponseAdapter create(HttpResponse response) {
+ String message;
+ try {
+ message = EntityUtils.toString(response.getEntity());
+ } catch (IllegalArgumentException | IOException e) {
+ LOGGER.warn("Response from VES was empty");
+ message = "";
+ }
+ return new HttpResponseAdapter(response.getStatusLine().getStatusCode(), message);
+ }
+
+}
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java
index e7d113d..8cb6aa2 100644
--- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java
@@ -22,5 +22,6 @@ package org.onap.pnfsimulator.simulator.client;
public interface HttpClientAdapter {
- void send(String content);
+ HttpResponseAdapter send(String content);
+
}
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java
index 5d2a024..ba668fc 100644
--- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java
@@ -20,6 +20,8 @@
package org.onap.pnfsimulator.simulator.client;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
@@ -35,6 +37,9 @@ import org.slf4j.MarkerFactory;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.util.UUID;
@@ -48,11 +53,12 @@ public class HttpClientAdapterImpl implements HttpClientAdapter {
private static final String CONTENT_TYPE = "Content-Type";
private static final String APPLICATION_JSON = "application/json";
private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE");
+ private static final HttpApacheResponseAdapterFactory responseFactory = new HttpApacheResponseAdapterFactory();
private final HttpClient client;
private final String targetUrl;
public HttpClientAdapterImpl(String targetUrl, SslAuthenticationHelper sslAuthenticationHelper)
- throws IOException, GeneralSecurityException {
+ throws IOException, GeneralSecurityException {
this.client = HttpClientFactoryFacade.create(targetUrl, sslAuthenticationHelper);
this.targetUrl = targetUrl;
}
@@ -63,25 +69,34 @@ public class HttpClientAdapterImpl implements HttpClientAdapter {
}
@Override
- public void send(String content) {
+ public HttpResponseAdapter send(String content) {
+ HttpResponseAdapter vesResponse;
try {
HttpResponse response = sendAndRetrieve(content);
- EntityUtils.consumeQuietly(response.getEntity()); //response has to be fully consumed otherwise apache won't release connection
LOGGER.info(INVOKE, "Message sent, ves response code: {}", response.getStatusLine());
- } catch (IOException e) {
+ vesResponse = responseFactory.create(response);
+ EntityUtils.consumeQuietly(response.getEntity()); //response has to be fully consumed otherwise apache won't release connection
+ } catch (IOException | URISyntaxException e) {
LOGGER.warn("Error sending message to ves: {}", e.getMessage(), e.getCause());
+ vesResponse = new HttpResponseAdapter(421, String.format("Fail to connect with ves: %s", e.getMessage()));
}
+ return vesResponse;
}
- private HttpResponse sendAndRetrieve(String content) throws IOException {
+ private HttpResponse sendAndRetrieve(String content) throws IOException, URISyntaxException {
HttpPost request = createRequest(content);
HttpResponse httpResponse = client.execute(request);
request.releaseConnection();
return httpResponse;
}
- private HttpPost createRequest(String content) throws UnsupportedEncodingException {
- HttpPost request = new HttpPost(this.targetUrl);
+ private HttpPost createRequest(String content) throws UnsupportedEncodingException, URISyntaxException {
+ LOGGER.info("sending request using address: {}", this.targetUrl);
+ URI targetAddress = new URI(this.targetUrl);
+ HttpPost request = new HttpPost(targetAddress);
+ if(urlContainsUserInfo(targetAddress)) {
+ request.addHeader(HttpHeaders.AUTHORIZATION, getAuthenticationHeaderForUser(targetAddress.getUserInfo()));
+ }
StringEntity stringEntity = new StringEntity(content);
request.addHeader(CONTENT_TYPE, APPLICATION_JSON);
request.addHeader(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID));
@@ -90,4 +105,15 @@ public class HttpClientAdapterImpl implements HttpClientAdapter {
return request;
}
+ private boolean urlContainsUserInfo(URI targetAddress) {
+ return targetAddress.getUserInfo() != null && !targetAddress.getUserInfo().isEmpty();
+ }
+
+ private String getAuthenticationHeaderForUser(String userInfo) {
+ final byte[] encodedUserInfo = Base64.encodeBase64(
+ userInfo.getBytes(StandardCharsets.ISO_8859_1)
+ );
+ return String.format("Basic %s", new String(encodedUserInfo));
+ }
+
}
diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpResponseAdapter.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpResponseAdapter.java
new file mode 100644
index 0000000..e78b8a3
--- /dev/null
+++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpResponseAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.pnfsimulator.simulator.client;
+
+public class HttpResponseAdapter {
+
+ private final int code;
+ private final String message;
+
+ public HttpResponseAdapter(int code, String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+}
diff --git a/pnfsimulator/src/main/resources/application.properties b/pnfsimulator/src/main/resources/application.properties
index c566ce3..fddcec0 100644
--- a/pnfsimulator/src/main/resources/application.properties
+++ b/pnfsimulator/src/main/resources/application.properties
@@ -10,9 +10,9 @@ management.endpoint.configprops.enabled=true
management.endpoints.web.base-path=/
management.endpoints.web.exposure.include=refresh,health
-ssl.clientCertificateEnabled=true
+ssl.clientCertificateEnabled=${USE_CERTIFICATE_FOR_AUTHORIZATION:true}
ssl.strictHostnameVerification=${STRICT_HOSTNAME_VERIFICATION:false}
ssl.clientCertificatePath=/app/store/cert.p12
ssl.clientCertificatePasswordPath=/app/store/p12.pass
ssl.trustStorePath=/app/store/trust.jks
-ssl.trustStorePasswordPath=/app/store/trust.pass \ No newline at end of file
+ssl.trustStorePasswordPath=/app/store/truststore.pass
diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java
index 4fa5021..8dba750 100644
--- a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java
+++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java
@@ -36,6 +36,7 @@ import org.onap.pnfsimulator.rest.model.FullEvent;
import org.onap.pnfsimulator.rest.model.SimulatorParams;
import org.onap.pnfsimulator.rest.model.SimulatorRequest;
import org.onap.pnfsimulator.simulator.SimulatorService;
+import org.onap.pnfsimulator.simulator.client.HttpResponseAdapter;
import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig;
import org.quartz.SchedulerException;
import org.springframework.http.MediaType;
@@ -81,6 +82,7 @@ class SimulatorControllerTest {
private static final String SAMPLE_ID = "sampleId";
private static final Gson GSON_OBJ = new Gson();
private static final String JOB_NAME = "testJobName";
+ private static final HttpResponseAdapter TEST_HTTP_ACCEPTED_RESPONSE = new HttpResponseAdapter(202,"");
private static String simulatorRequestBody;
private MockMvc mockMvc;
@InjectMocks
@@ -103,6 +105,7 @@ class SimulatorControllerTest {
void setup() throws IOException, SchedulerException, GeneralSecurityException {
MockitoAnnotations.initMocks(this);
when(simulatorService.triggerEvent(any())).thenReturn("jobName");
+ when(simulatorService.triggerOneTimeEvent(any())).thenReturn(TEST_HTTP_ACCEPTED_RESPONSE);
mockMvc = MockMvcBuilders
.standaloneSetup(controller)
.build();
diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java
index 45e1ed4..d5426ec 100644
--- a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java
+++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java
@@ -24,6 +24,7 @@ import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
+import org.apache.http.HttpStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -33,6 +34,8 @@ import org.onap.pnfsimulator.rest.model.FullEvent;
import org.onap.pnfsimulator.rest.model.SimulatorParams;
import org.onap.pnfsimulator.rest.model.SimulatorRequest;
import org.onap.pnfsimulator.simulator.client.HttpClientAdapter;
+import org.onap.pnfsimulator.simulator.client.HttpResponseAdapter;
+import org.onap.pnfsimulator.simulator.client.HttpTestUtils;
import org.onap.pnfsimulator.simulator.client.utils.ssl.SslAuthenticationHelper;
import org.onap.pnfsimulator.simulator.scheduler.EventScheduler;
import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig;
@@ -46,12 +49,9 @@ import java.security.GeneralSecurityException;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -67,7 +67,7 @@ class SimulatorServiceTest {
private static final JsonObject VALID_PATCH = GSON.fromJson("{\"event\": {\n"
+ " \"commonEventHeader\": {\n"
+ " \"sourceName\": \"SomeCustomSource\"}}}\n", JsonObject.class);
- private static JsonObject VALID_FULL_EVENT = GSON.fromJson("{\"event\": {\n"
+ private static final JsonObject VALID_FULL_EVENT = GSON.fromJson("{\"event\": {\n"
+ " \"commonEventHeader\": {\n"
+ " \"domain\": \"notification\",\n"
+ " \"eventName\": \"vFirewallBroadcastPackets\"\n"
@@ -77,7 +77,7 @@ class SimulatorServiceTest {
+ " \"name\": \"A20161221.1031-1041.bin.gz\",\n"
+ " \"hashMap\": {\n"
+ " \"fileformatType\": \"org.3GPP.32.435#measCollec\"}}]}}}", JsonObject.class);
- private static JsonObject FULL_EVENT_WITH_KEYWORDS = GSON.fromJson("{\"event\":{ \n"
+ private static final JsonObject FULL_EVENT_WITH_KEYWORDS = GSON.fromJson("{\"event\":{ \n"
+ " \"commonEventHeader\":{ \n"
+ " \"domain\":\"notification\",\n"
+ " \"eventName\":\"#RandomString(20)\",\n"
@@ -99,14 +99,15 @@ class SimulatorServiceTest {
private final ArgumentCaptor<String> eventIdCaptor = ArgumentCaptor.forClass(String.class);
private final ArgumentCaptor<String> vesUrlCaptor = ArgumentCaptor.forClass(String.class);
private final ArgumentCaptor<String> eventContentCaptor = ArgumentCaptor.forClass(String.class);
+ private final SslAuthenticationHelper sslAuthenticationHelper = new SslAuthenticationHelper();
+ private final TemplatePatcher templatePatcher = new TemplatePatcher();
+ private final TemplateReader templateReader = new FilesystemTemplateReader(
+ "src/test/resources/org/onap/pnfsimulator/simulator/", GSON);
+
private SimulatorService simulatorService;
private EventDataService eventDataService;
private EventScheduler eventScheduler;
private SimulatorConfigService simulatorConfigService;
- private SslAuthenticationHelper sslAuthenticationHelper = new SslAuthenticationHelper() ;
- private static TemplatePatcher templatePatcher = new TemplatePatcher();
- private static TemplateReader templateReader = new FilesystemTemplateReader(
- "src/test/resources/org/onap/pnfsimulator/simulator/", GSON);
@BeforeEach
void setUp() throws MalformedURLException {
@@ -197,8 +198,7 @@ class SimulatorServiceTest {
new SslAuthenticationHelper()));
HttpClientAdapter adapterMock = mock(HttpClientAdapter.class);
- doNothing().when(adapterMock).send(eventContentCaptor.capture());
- doReturn(adapterMock).when(spiedTestedService).createHttpClientAdapter(any(String.class));
+ prepareMocksWithAcceptedResponse(spiedTestedService, adapterMock);
FullEvent event = new FullEvent(VES_URL, VALID_FULL_EVENT);
spiedTestedService.triggerOneTimeEvent(event);
@@ -218,8 +218,7 @@ class SimulatorServiceTest {
);
HttpClientAdapter adapterMock = mock(HttpClientAdapter.class);
- doNothing().when(adapterMock).send(eventContentCaptor.capture());
- doReturn(adapterMock).when(spiedTestedService).createHttpClientAdapter(any(String.class));
+ prepareMocksWithAcceptedResponse(spiedTestedService, adapterMock);
FullEvent event = new FullEvent(VES_URL, FULL_EVENT_WITH_KEYWORDS);
spiedTestedService.triggerOneTimeEvent(event);
@@ -262,6 +261,12 @@ class SimulatorServiceTest {
assertTrue(simulatorService.cancelEvent(jobName));
}
+ private void prepareMocksWithAcceptedResponse(SimulatorService spiedTestedService, HttpClientAdapter adapterMock) throws IOException, GeneralSecurityException {
+ HttpResponseAdapter response = new HttpResponseAdapter(HttpStatus.SC_ACCEPTED, HttpTestUtils.HTTP_MESSAGE_ACCEPTER);
+ doReturn(response).when(adapterMock).send(eventContentCaptor.capture());
+ doReturn(adapterMock).when(spiedTestedService).createHttpClientAdapter(any(String.class));
+ }
+
private void assertEventHasExpectedStructure(String expectedVesUrl, String templateName, String sourceNameString) throws SchedulerException, IOException, GeneralSecurityException {
verify(eventScheduler, times(1)).scheduleEvent(vesUrlCaptor.capture(), intervalCaptor.capture(),
repeatCountCaptor.capture(), templateNameCaptor.capture(), eventIdCaptor.capture(), bodyCaptor.capture());
diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactoryTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactoryTest.java
new file mode 100644
index 0000000..2f8c6b3
--- /dev/null
+++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpApacheResponseAdapterFactoryTest.java
@@ -0,0 +1,98 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.pnfsimulator.simulator.client;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.BeforeEach;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.onap.pnfsimulator.simulator.client.HttpTestUtils.createMockedHttpEntity;
+import static org.onap.pnfsimulator.simulator.client.HttpTestUtils.createStatusLine;
+
+class HttpApacheResponseAdapterFactoryTest {
+
+ private HttpResponse httpResponse;
+
+ @BeforeEach
+ void setup() {
+ httpResponse = mock(HttpResponse.class);
+ }
+
+ @Test
+ void shouldCreateCorrectHttpResponseAdapterFromApacheHttpAcceptedResponse() throws IOException {
+ // given
+ final int responseCode = HttpStatus.SC_ACCEPTED;
+ final String responseBody = HttpTestUtils.HTTP_MESSAGE_ACCEPTER;
+ prepareHttpResponseMock(responseCode, createMockedHttpEntity(responseBody));
+
+ // when
+ HttpResponseAdapter httpResponseAdapter = new HttpApacheResponseAdapterFactory().create(httpResponse);
+
+ // then
+ assertHttpResponseIsCorrect(responseCode, responseBody, httpResponseAdapter);
+ }
+
+
+ @Test
+ void shouldCreateCorrectHttpResponseAdapterFromApacheHttpForbiddenResponse() throws IOException {
+ // given
+ final int responseCode = HttpStatus.SC_FORBIDDEN;
+ final String responseBody = HttpTestUtils.HTTP_MESSAGE_FORBIDDEN;
+ prepareHttpResponseMock(responseCode, createMockedHttpEntity(responseBody));
+
+ // when
+ HttpResponseAdapter httpResponseAdapter = new HttpApacheResponseAdapterFactory().create(httpResponse);
+
+ // then
+ assertHttpResponseIsCorrect(responseCode, responseBody, httpResponseAdapter);
+ }
+
+ @Test
+ void shouldCreateCorrectHttpResponseAdapterFromApacheHttpResponseWithEmptyEntity() {
+ // given
+ final int responseCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
+ prepareHttpResponseMock(responseCode, null);
+
+ // when
+ HttpResponseAdapter httpResponseAdapter = new HttpApacheResponseAdapterFactory().create(httpResponse);
+
+
+ assertHttpResponseIsCorrect(responseCode, "", httpResponseAdapter);
+ }
+
+ private void prepareHttpResponseMock(int responseCode, HttpEntity httpEntity) {
+ doReturn(createStatusLine(responseCode)).when(httpResponse).getStatusLine();
+ doReturn(httpEntity).when(httpResponse).getEntity();
+ }
+
+ private void assertHttpResponseIsCorrect(int responseCode, String responseBody, HttpResponseAdapter httpResponseAdapter) {
+ assertEquals(responseCode, httpResponseAdapter.getCode());
+ assertEquals(responseBody, httpResponseAdapter.getMessage());
+ }
+
+}
diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java
index 9eaab5c..cfbc8c1 100644
--- a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java
+++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java
@@ -20,24 +20,37 @@
package org.onap.pnfsimulator.simulator.client;
+import org.apache.http.Header;
+import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.message.BasicHeader;
+import org.apache.tomcat.util.codec.binary.Base64;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import org.onap.pnfsimulator.simulator.client.utils.ssl.SslAuthenticationHelper;
import java.io.IOException;
import java.net.MalformedURLException;
+import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
+import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.onap.pnfsimulator.simulator.client.HttpTestUtils.createMockedHttpEntity;
+import static org.onap.pnfsimulator.simulator.client.HttpTestUtils.createStatusLine;
class HttpClientAdapterImplTest {
@@ -55,12 +68,28 @@ class HttpClientAdapterImplTest {
@Test
void sendShouldSuccessfullySendRequestGivenValidUrl() throws IOException {
- assertAdapterSentRequest("http://valid-url:8080");
+ assertAdapterSentRequest("http://valid-url:8080",
+ HttpStatus.SC_FORBIDDEN, HttpTestUtils.HTTP_MESSAGE_FORBIDDEN);
}
@Test
void sendShouldSuccessfullySendRequestGivenValidUrlUsingHttps() throws IOException {
- assertAdapterSentRequest("https://valid-url:8443");
+ assertAdapterSentRequest("https://valid-url:8443",
+ HttpStatus.SC_ACCEPTED, HttpTestUtils.HTTP_MESSAGE_ACCEPTER);
+ }
+
+ @Test
+ void sendShouldSuccessfullySendRequestUsingBasicAuth() throws IOException {
+ String testUserInfo = "user1:pass1";
+ Header authorizationHeader = createAuthorizationHeader(testUserInfo);
+ assertAdapterSentRequest("https://" + testUserInfo + "@valid-url:8443",
+ HttpStatus.SC_ACCEPTED, HttpTestUtils.HTTP_MESSAGE_ACCEPTER,
+ List.of(authorizationHeader));
+ }
+
+ @Test
+ void sendShouldFailToSendRequestGivenInvalidUrlUsingAdnShouldInformUser() throws IOException {
+ assertAdapterInformsUserWhenServiceIsUnavailable("https://invalid-url:8080");
}
@Test
@@ -88,13 +117,41 @@ class HttpClientAdapterImplTest {
}
}
- private void assertAdapterSentRequest(String targetUrl) throws IOException {
+ private Header createAuthorizationHeader(String testUserInfo) {
+ String encodedUserInfo = new String(Base64.encodeBase64(testUserInfo.getBytes(StandardCharsets.UTF_8)));
+ return new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encodedUserInfo);
+ }
+
+ private void assertAdapterSentRequest(String targetUrl, int responseCode, String responseMessage) throws IOException {
+ assertAdapterSentRequest(targetUrl, responseCode, responseMessage, List.of());
+ }
+
+ private void assertAdapterSentRequest(String targetUrl, int responseCode, String responseMessage, List<Header> expectedHeaders) throws IOException {
HttpClientAdapter adapter = new HttpClientAdapterImpl(httpClient, targetUrl);
doReturn(httpResponse).when(httpClient).execute(any());
+ doReturn(createStatusLine(responseCode)).when(httpResponse).getStatusLine();
+ doReturn(createMockedHttpEntity(responseMessage)).when(httpResponse).getEntity();
+
+ HttpResponseAdapter response = adapter.send("test-msg");
+
+ ArgumentCaptor<HttpPost> httpPostCaptor = ArgumentCaptor.forClass(HttpPost.class);
+ verify(httpClient).execute(httpPostCaptor.capture());
+ Header[] headers = httpPostCaptor.getValue().getAllHeaders();
+ assertEquals(responseCode, response.getCode());
+ assertEquals(responseMessage, response.getMessage());
+ assertThat(headers).usingFieldByFieldElementComparator().containsAll(expectedHeaders);
+ }
+
+ private void assertAdapterInformsUserWhenServiceIsUnavailable(String targetUrl) throws IOException {
+ HttpClientAdapter adapter = new HttpClientAdapterImpl(httpClient, targetUrl);
+ String exceptionMessage = "test message";
+ doThrow(new IOException(exceptionMessage)).when(httpClient).execute(any());
- adapter.send("test-msg");
+ HttpResponseAdapter response = adapter.send("test-msg");
verify(httpClient).execute(any());
- verify(httpResponse).getStatusLine();
+ assertEquals(421, response.getCode());
+ assertEquals(String.format("Fail to connect with ves: %s", exceptionMessage), response.getMessage());
}
+
}
diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpTestUtils.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpTestUtils.java
new file mode 100644
index 0000000..02ff531
--- /dev/null
+++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpTestUtils.java
@@ -0,0 +1,55 @@
+/*
+ * ============LICENSE_START=======================================================
+ * PNF-REGISTRATION-HANDLER
+ * ================================================================================
+ * Copyright (C) 2021 Nokia. All rights reserved.
+ * ================================================================================
+ * 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.pnfsimulator.simulator.client;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.ProtocolVersion;
+import org.apache.http.message.BasicStatusLine;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+public class HttpTestUtils {
+
+ private HttpTestUtils() {
+ }
+
+ public static final String HTTP_MESSAGE_ACCEPTER = "Accepted";
+ public static final String HTTP_MESSAGE_FORBIDDEN = "Forbidden";
+
+ static HttpEntity createMockedHttpEntity(String responseBody) throws IOException {
+ HttpEntity httpEntity = mock(HttpEntity.class);
+ doReturn(new ByteArrayInputStream(responseBody.getBytes())).when(httpEntity).getContent();
+ return httpEntity;
+ }
+
+ static BasicStatusLine createStatusLine(int responseCode) {
+ return new BasicStatusLine(
+ new ProtocolVersion("1.0.0", 1, 0),
+ responseCode,
+ ""
+ );
+ }
+
+}