aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--netconfsimulator/src/it/java/integration/NetconfFunctionsIT.java53
-rw-r--r--netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java6
-rw-r--r--pnfsimulator/integration/src/test/java/org/onap/pnfsimulator/integration/BasicAvailabilityTest.java27
-rw-r--r--pnfsimulator/src/main/resources/application.properties8
-rw-r--r--sanitycheck/tools/README.md93
-rw-r--r--sanitycheck/tools/docker-compose.yml71
6 files changed, 229 insertions, 29 deletions
diff --git a/netconfsimulator/src/it/java/integration/NetconfFunctionsIT.java b/netconfsimulator/src/it/java/integration/NetconfFunctionsIT.java
index 5d1a25a..495714b 100644
--- a/netconfsimulator/src/it/java/integration/NetconfFunctionsIT.java
+++ b/netconfsimulator/src/it/java/integration/NetconfFunctionsIT.java
@@ -53,6 +53,10 @@ import static org.assertj.core.api.Assertions.assertThat;
@RunWith(BeforeAfterSpringTestRunner.class)
public class NetconfFunctionsIT {
+ private static final String NEW_YANG_MODEL_NAME = "newyangmodel";
+ private static final String NEW_YANG_MODEL_FILE = "newYangModel.yang";
+ private static final String INITIAL_CONFIG_XML_FILE = "initialConfig.xml";
+ private static final String CONFIG_NAME = "config2";
private static NetconfSimulatorClient client;
private static ObjectMapper objectMapper;
@@ -104,7 +108,7 @@ public class NetconfFunctionsIT {
public void testShouldLoadModelEditConfigurationAndDeleteModule() throws IOException {
// do load
try (CloseableHttpResponse response = client
- .loadModel("newyangmodel", "newYangModel.yang", "initialConfig.xml")) {
+ .loadModel(NEW_YANG_MODEL_NAME, NEW_YANG_MODEL_FILE, INITIAL_CONFIG_XML_FILE)) {
assertResponseStatusCode(response, HttpStatus.OK);
String original = client.getResponseContentAsString(response);
assertThat(original).isEqualTo("\"Successfully started\"\n");
@@ -116,7 +120,7 @@ public class NetconfFunctionsIT {
assertThat(afterUpdateConfigContent).isEqualTo("New configuration has been activated");
}
// do delete
- try (CloseableHttpResponse deleteResponse = client.deleteModel("newyangmodel")) {
+ try (CloseableHttpResponse deleteResponse = client.deleteModel(NEW_YANG_MODEL_NAME)) {
assertResponseStatusCode(deleteResponse, HttpStatus.OK);
String original = client.getResponseContentAsString(deleteResponse);
assertThat(original).isEqualTo("\"Successfully deleted\"\n");
@@ -179,7 +183,7 @@ public class NetconfFunctionsIT {
@Test
public void testShouldLoadNewYangModelAndReconfigure() throws IOException {
try (CloseableHttpResponse response = client
- .loadModel("newyangmodel", "newYangModel.yang", "initialConfig.xml")) {
+ .loadModel(NEW_YANG_MODEL_NAME, NEW_YANG_MODEL_FILE, INITIAL_CONFIG_XML_FILE)) {
assertResponseStatusCode(response, HttpStatus.OK);
String original = client.getResponseContentAsString(response);
@@ -188,23 +192,44 @@ public class NetconfFunctionsIT {
}
}
- // ToDo: fix this integration test
- // https://jira.onap.org/browse/INT-1535
- public void shouldGetLoadedModelByName() throws IOException {
+ @Test
+ public void shouldGetLoadedModelByName() throws IOException, InterruptedException {
testShouldLoadNewYangModelAndReconfigure();
- try (CloseableHttpResponse response = client.getConfigByModelAndContainerNames("newyangmodel", "config2")) {
- assertResponseStatusCode(response, HttpStatus.OK);
- String config = client.getResponseContentAsString(response);
-
- assertThat(config).isEqualTo(
- "<config2 xmlns=\"http://onap.org/newyangmodel\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
- + " <item1>100</item1>\n"
- + "</config2>\n");
+ if(checkIfModelIsPresentWithRetry(NEW_YANG_MODEL_NAME, CONFIG_NAME,4,500)) {
+ try (CloseableHttpResponse response = client.getConfigByModelAndContainerNames(NEW_YANG_MODEL_NAME, CONFIG_NAME)) {
+ assertResponseStatusCode(response, HttpStatus.OK);
+ String config = client.getResponseContentAsString(response);
+
+ assertThat(config).isEqualTo(
+ "<config2 xmlns=\"http://onap.org/newyangmodel\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n"
+ + " <item1>100</item1>\n"
+ + "</config2>\n");
+ }
+ } else {
+ fail("Could not find new YANG model by name");
}
}
+ private boolean checkIfModelIsPresentWithRetry(String model, String container,int retryCount,int interval) throws IOException, InterruptedException {
+ boolean isModelPresent = false;
+
+ for(int i=0 ; i<retryCount ; i++ ) {
+ try (CloseableHttpResponse response =
+ client.getConfigByModelAndContainerNames(model, container)) {
+ if( response.getStatusLine().getStatusCode() == HttpStatus.BAD_REQUEST.value() ) {
+ System.out.println("New yang model not present on kafka, retrying in " + interval + " ms.");
+ Thread.sleep(interval);
+ } else {
+ isModelPresent = true;
+ break;
+ }
+ }
+ }
+ return isModelPresent;
+ }
+
private void assertResponseStatusCode(HttpResponse response, HttpStatus expectedStatus) {
assertThat(response.getStatusLine().getStatusCode()).isEqualTo(expectedStatus.value());
}
diff --git a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java
index 6bd8390..8f0f0cf 100644
--- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java
+++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java
@@ -33,13 +33,14 @@ import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.NoSuchElementException;
@Slf4j
@Service
public class StoreService {
private static final String CONFIG_TOPIC = "config";
- private static final long CONSUMING_DURATION_IN_MS = 1000;
+ private static final long CONSUMING_DURATION_IN_MS = 5000;
private ConsumerFactory<String, String> consumerFactory;
static final List<String> TOPICS_TO_SUBSCRIBE = Collections.singletonList(CONFIG_TOPIC);
@@ -69,6 +70,9 @@ public class StoreService {
ConsumerRecords<String, String> consumerRecords = pollConsumerRecords(consumer);
consumerRecords.forEach(consumerRecord ->
messages.add(new Message(consumerRecord.timestamp(), consumerRecord.value())));
+ } catch (NoSuchElementException e) {
+ log.warn("not able to create consumer and to poll messages");
+ return Collections.emptyList();
}
return messages;
}
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 9f11a00..fffc447 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
@@ -7,9 +7,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* 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.
@@ -26,6 +26,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.hamcrest.Matchers.equalTo;
import com.google.gson.JsonObject;
+
import java.io.IOException;
import java.net.Inet4Address;
import java.net.NetworkInterface;
@@ -35,6 +36,8 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.UUID;
+
+import io.restassured.response.Response;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -46,12 +49,15 @@ import org.mockito.internal.verification.VerificationOverTimeImpl;
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 BasicAvailabilityTest {
+ private static final int VERIFICATION_TIMEOUT_MILLIS = 10000;
+
@Autowired
VesSimulatorController vesSimulatorController;
@@ -73,7 +79,7 @@ public class BasicAvailabilityTest {
}
@Test
- public void simulatorShouldFailWhenTriggeredNonexistentTemplate(){
+ public void simulatorShouldFailWhenTriggeredNonexistentTemplate() {
//given
String startUrl = prepareRequestUrl(ACTION_START);
String body = "{\n"
@@ -93,7 +99,7 @@ public class BasicAvailabilityTest {
.when()
.post(startUrl)
.then()
- .statusCode(400)
+ .statusCode(HttpStatus.BAD_REQUEST.value())
.body("message", equalTo("Cannot start simulator - template any_nonexistent_template.json not found."));
}
@@ -119,11 +125,11 @@ public class BasicAvailabilityTest {
.when()
.post(startUrl)
.then()
- .statusCode(200)
+ .statusCode(HttpStatus.OK.value())
.body("message", equalTo("Request started"));
Mockito.verify(vesSimulatorService,
- Mockito.timeout(3000))
+ Mockito.timeout(VERIFICATION_TIMEOUT_MILLIS))
.sendEventToDmaapV5(parameterCaptor.capture());
assertThat(parameterCaptor.getValue()
@@ -142,7 +148,7 @@ public class BasicAvailabilityTest {
when()
.post(cancelAllUrl)
.then()
- .statusCode(200)
+ .statusCode(HttpStatus.OK.value())
.body("message", equalTo("Event(s) was cancelled"));
}
@@ -167,7 +173,7 @@ public class BasicAvailabilityTest {
Path newFile = Files.createFile(Paths.get("..", "templates", fileName));
Files.write(newFile, templateBody.getBytes());
- given()
+ Response postResponse = given()
.contentType("application/json")
.body(requestBody)
.when()
@@ -176,7 +182,8 @@ public class BasicAvailabilityTest {
Files.delete(newFile);
//then
- Mockito.verify(vesSimulatorService, Mockito.timeout(3000))
+ assertThat(postResponse.statusCode()).isEqualTo(HttpStatus.OK.value());
+ Mockito.verify(vesSimulatorService, Mockito.timeout(VERIFICATION_TIMEOUT_MILLIS))
.sendEventToDmaapV5(parameterCaptor.capture());
assertThat(parameterCaptor.getValue()
.get("fake").getAsString()).isEqualTo("template");
@@ -205,7 +212,7 @@ public class BasicAvailabilityTest {
.when()
.post(startUrl)
.then()
- .statusCode(200)
+ .statusCode(HttpStatus.OK.value())
.body("message", equalTo("Request started"));
VerificationOverTimeImpl verificator = new VerificationOverTimeImpl(100, Mockito.times(4), false, new Timer(6000));
diff --git a/pnfsimulator/src/main/resources/application.properties b/pnfsimulator/src/main/resources/application.properties
index 07a28dc..5c573b3 100644
--- a/pnfsimulator/src/main/resources/application.properties
+++ b/pnfsimulator/src/main/resources/application.properties
@@ -11,7 +11,7 @@ management.endpoints.web.base-path=/
management.endpoints.web.exposure.include=refresh,health
ssl.clientCertificateEnabled=true
-ssl.clientCertificateDir=/app/store/client.p12
-ssl.clientCertificatePassword=collector
-ssl.trustStoreDir=/app/store/trustStore
-ssl.trustStorePassword=collector
+ssl.clientCertificateDir=/app/store/cert.p12
+ssl.clientCertificatePassword=${CLIENT_CERT_PASS}
+ssl.trustStoreDir=/app/store/trust.jks
+ssl.trustStorePassword=${TRUST_CERT_PASS}
diff --git a/sanitycheck/tools/README.md b/sanitycheck/tools/README.md
new file mode 100644
index 0000000..2d6b3d0
--- /dev/null
+++ b/sanitycheck/tools/README.md
@@ -0,0 +1,93 @@
+Standalone PNF Simulator configuration for HTTPS communication with VES
+------------------------
+
+### Description
+
+docker-compose.yml prepares PNF simulator container for HTTPS communication with VES.
+
+When docker-compose starts certs-init container fills connected volume with certificates, truststores, keystores,
+passwords etc. Next pnf-simulator container starts and connects to the same volume. On startup it should read password
+values from proper files and set them in system environment variables. With these variables and files in volume
+application is ready to work on HTTPS.
+
+### Prerequisites
+
+1. certs-init container works with external AAF on cloud. Due to that fact it must have set correct IPs to workers that
+has access to AAF. In docker-compose.yml fields with mentioned IPs are:
+
+ * aaf-locate.onap
+ * aaf-cm.onap
+ * aaf-service.onap
+
+### Start
+
+**ATTENTION**
+
+Proper IPs to AAF must be set in the docker-compose.yml before start (as described in prerequisites)!
+
+```
+docker-compose up
+```
+
+### Send event
+
+**ATTENTION**
+
+``sanitycheck/events/eventToVes.json`` file which is request for sending event to VES must have correct ``vesServerURL``
+field before sending event.
+IP of ``vesServerURL`` should be the same as given in docker-compose.yml in ``aaf-locate.onap`` field.
+To use secured connection remember about setting protocol to https:// and port to proper secured port of VES.
+
+To send event from PNF simulator to VES use this command from ``pnf-simulator/sanitycheck`` directory:
+
+````
+make generate-event
+````
+
+Sample ``sanitycheck/events/eventToVes.json`` file content is:
+
+```json
+{
+ "vesServerUrl": "https://10.183.35.177:30417/eventListener/v7",
+ "event": {
+ "event": {
+ "commonEventHeader": {
+ "version": "4.0.1",
+ "vesEventListenerVersion": "7.0.1",
+ "domain": "fault",
+ "eventName": "Fault_Vscf:Acs-Ericcson_PilotNumberPoolExhaustion",
+ "eventId": "fault0000245",
+ "sequence": 1,
+ "priority": "High",
+ "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234",
+ "reportingEntityName": "ibcx0001vm002oam001",
+ "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014",
+ "sourceName": "scfx0001vm002cap001",
+ "nfVendorName": "Ericsson",
+ "nfNamingCode": "scfx",
+ "nfcNamingCode": "ssc",
+ "startEpochMicrosec": 1413378172000000,
+ "lastEpochMicrosec": 1413378172000000,
+ "timeZoneOffset": "UTC-05:30"
+ },
+ "faultFields": {
+ "faultFieldsVersion": "4.0",
+ "alarmCondition": "PilotNumberPoolExhaustion",
+ "eventSourceType": "other",
+ "specificProblem": "Calls cannot complete - pilot numbers are unavailable",
+ "eventSeverity": "CRITICAL",
+ "vfStatus": "Active",
+ "alarmAdditionalInformation": {
+ "PilotNumberPoolSize": "1000"
+ }
+ }
+ }
+ }
+}
+
+```
+
+### Stop
+```
+docker-compose down
+``` \ No newline at end of file
diff --git a/sanitycheck/tools/docker-compose.yml b/sanitycheck/tools/docker-compose.yml
new file mode 100644
index 0000000..3016189
--- /dev/null
+++ b/sanitycheck/tools/docker-compose.yml
@@ -0,0 +1,71 @@
+version: '3'
+
+networks:
+ tls-init-network:
+
+volumes:
+ certs-volume:
+
+services:
+ certs-init:
+ image: nexus3.onap.org:10001/onap/org.onap.dcaegen2.deployments.tls-init-container:2.1.0
+ extra_hosts:
+ #set worker IP with access to AAF
+ aaf-locate.onap: 10.183.35.177
+ aaf-cm.onap: 10.183.35.177
+ aaf-service.onap: 10.183.35.177
+ environment:
+ - aaf_locate_url=https://aaf-locate.onap:31111
+ - aaf_url_cm=https://aaf-cm.onap:31114
+ - aaf_url=https://aaf-service.onap:31110
+ networks:
+ - tls-init-network
+ volumes:
+ - certs-volume:/opt/app/osaaf
+ mongo:
+ image: mongo
+ restart: always
+ environment:
+ MONGO_INITDB_ROOT_USERNAME: root
+ MONGO_INITDB_ROOT_PASSWORD: zXcVbN123!
+ MONGO_INITDB_DATABASE: pnf_simulator
+ networks:
+ - tls-init-network
+ volumes:
+ - ../../pnfsimulator/db:/docker-entrypoint-initdb.d
+ ports:
+ - "27017:27017"
+
+ mongo-express:
+ image: mongo-express
+ restart: always
+ ports:
+ - 8081:8081
+ networks:
+ - tls-init-network
+ environment:
+ ME_CONFIG_MONGODB_ADMINUSERNAME: root
+ ME_CONFIG_MONGODB_ADMINPASSWORD: zXcVbN123!
+
+ pnf-simulator:
+ image: nexus3.onap.org:10001/onap/org.onap.integration.simulators.pnfsimulator
+ ports:
+ - "5000:5000"
+ command: bash -c "
+ while [[ $$(ls -1 /app/store | wc -l) != '10' ]]; do echo 'Waiting for certs...'; sleep 3; done
+ && export CLIENT_CERT_PASS=$$(cat /app/store/p12.pass)
+ && export TRUST_CERT_PASS=$$(cat /app/store/trust.pass)
+ && java -Dspring.config.location=file:/app/application.properties -cp /app/libs/*:/app/pnf-simulator.jar org.onap.pnfsimulator.Main
+ "
+ volumes:
+ - ../../pnfsimulator/logs:/var/log
+ - ../../pnfsimulator/templates:/app/templates
+ - ../../pnfsimulator/src/main/resources/application.properties:/app/application.properties
+ - certs-volume:/app/store
+ networks:
+ - tls-init-network
+ restart: on-failure
+ depends_on:
+ - certs-init
+ - mongo
+ - mongo-express