diff options
50 files changed, 667 insertions, 154 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..cb456c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ +create-sonarqube: + @echo "##### Create SonarQube #####" + docker run -d --name sonarqube -p 9000:9000 -p 9092:9092 sonarqube + @echo "************************************************" + @echo "*** Follow instructions from README_SONAR.md ***" + @echo "************************************************" + @echo "##### DONE #####" + +start-sonarqube: + @echo "##### Start SonarQube #####" + docker start sonarqube + @echo "************************************************" + @echo "*** Follow instructions from README_SONAR.md ***" + @echo "************************************************" + @echo "##### DONE #####" + +stop-sonarqube: + @echo "##### Stop SonarQube #####" + docker stop sonarqube + @echo "##### DONE #####" + @@ -21,6 +21,10 @@ mvn clean package mvn clean package -P docker -DskipTests=true ``` +##Sanity check + +See README.md in sanitycheck directory + ## Sonar https://sonarcloud.io/dashboard?id=onap_integration-pnf-simulator diff --git a/README_SONAR.md b/README_SONAR.md new file mode 100644 index 0000000..e65b7e6 --- /dev/null +++ b/README_SONAR.md @@ -0,0 +1,73 @@ +# Run SonarQube locally +All instructions based at an article at https://www.vogella.com/tutorials/SonarQube/article.html + +## Configure and run SonarQube locally +* Create and run SonarQube container + ``` + make create-sonarqube + ``` +* Configure SonarQube + + a). Log in at http://localhost:9000 + + ![alt text](docs/sonarqube/login_sonarqube.png "Log in") + + Username: admin + Password: admin + + b). Create a new Sonar project. + + ![alt text](docs/sonarqube/create_new_project_sonarqube.png "Create a new project") + + - Set project name + + ![alt text](docs/sonarqube/create_new_project_step1_sonarqube.png "Set project name") + + - Generate token + + ![alt text](docs/sonarqube/create_new_project_step2_sonarqube.png "Generate token") + + You should see + + ![alt text](docs/sonarqube/create_new_project_step3_sonarqube.png "Generated token") + + - Select code language and building technology + + ![alt text](docs/sonarqube/create_new_project_step4_sonarqube.png "Select code language") + + c). Run code analyse using command from a previous step. + + Before code analyse ALWAYS execute: + + ``` + mvn clean test + ``` + + Next (from previous step): + ``` + mvn sonar:sonar \ + -Dsonar.projectKey=pnf-simulator \ + -Dsonar.host.url=http://localhost:9000 \ + -Dsonar.login=de5dac7da79a4de88876006a05457902aab1a3a3 + ``` + After command execution you should see at the console: + ``` + [INFO] ANALYSIS SUCCESSFUL, you can browse http://localhost:9000/dashboard?id=pnf-simulator + [INFO] Note that you will be able to access the updated dashboard once the server has processed the submitted analysis report + ``` + Click at link http://localhost:9000/dashboard?id=pnf-simulator to see Sonar report + ![alt text](docs/sonarqube/sonarqube_report.png "Select code language") + + IMPORTANT: Please note command used to run code analise. You will need it later. + +## Stopping SonarQube +If you do not want to repeat step **Configure and run SonarQube locally** you must use stopping and starting make goals. +``` + make stop-sonarqube +``` + +## Starting SonarQube +If you do not want to repeat step **Configure and run SonarQube locally** you must use stopping and starting make goals. +``` + make start-sonarqube +``` diff --git a/docs/sonarqube/create_new_project_sonarqube.png b/docs/sonarqube/create_new_project_sonarqube.png Binary files differnew file mode 100644 index 0000000..0d41700 --- /dev/null +++ b/docs/sonarqube/create_new_project_sonarqube.png diff --git a/docs/sonarqube/create_new_project_step1_sonarqube.png b/docs/sonarqube/create_new_project_step1_sonarqube.png Binary files differnew file mode 100644 index 0000000..5601672 --- /dev/null +++ b/docs/sonarqube/create_new_project_step1_sonarqube.png diff --git a/docs/sonarqube/create_new_project_step2_sonarqube.png b/docs/sonarqube/create_new_project_step2_sonarqube.png Binary files differnew file mode 100644 index 0000000..0e759dc --- /dev/null +++ b/docs/sonarqube/create_new_project_step2_sonarqube.png diff --git a/docs/sonarqube/create_new_project_step3_sonarqube.png b/docs/sonarqube/create_new_project_step3_sonarqube.png Binary files differnew file mode 100644 index 0000000..be8b1a1 --- /dev/null +++ b/docs/sonarqube/create_new_project_step3_sonarqube.png diff --git a/docs/sonarqube/create_new_project_step4_sonarqube.png b/docs/sonarqube/create_new_project_step4_sonarqube.png Binary files differnew file mode 100644 index 0000000..810b35f --- /dev/null +++ b/docs/sonarqube/create_new_project_step4_sonarqube.png diff --git a/docs/sonarqube/login_sonarqube.png b/docs/sonarqube/login_sonarqube.png Binary files differnew file mode 100644 index 0000000..4810cf0 --- /dev/null +++ b/docs/sonarqube/login_sonarqube.png diff --git a/docs/sonarqube/sonarqube_report.png b/docs/sonarqube/sonarqube_report.png Binary files differnew file mode 100644 index 0000000..925d256 --- /dev/null +++ b/docs/sonarqube/sonarqube_report.png diff --git a/netconfsimulator/Dockerfile_app b/netconfsimulator/Dockerfile_app index 589be17..d1cc447 100644 --- a/netconfsimulator/Dockerfile_app +++ b/netconfsimulator/Dockerfile_app @@ -1,4 +1,4 @@ -FROM docker.io/openjdk:8-jre-alpine +FROM docker.io/openjdk:11-jre-slim ARG VERSION=${version} diff --git a/netconfsimulator/pom.xml b/netconfsimulator/pom.xml index 86f3ecd..6dbdf0c 100644 --- a/netconfsimulator/pom.xml +++ b/netconfsimulator/pom.xml @@ -35,8 +35,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> + <maven.compiler.source>11</maven.compiler.source> + <maven.compiler.target>11</maven.compiler.target> <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format> <docker.registry>nexus3.onap.org:10003</docker.registry> <docker.image.tag>latest</docker.image.tag> diff --git a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/MessageDTO.java b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/Message.java index 4311cd6..9a7debc 100644 --- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/MessageDTO.java +++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/Message.java @@ -25,7 +25,7 @@ import lombok.Getter; @Getter @AllArgsConstructor -class MessageDTO { +class Message { private long timestamp; private String configuration; } diff --git a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreController.java b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreController.java index 2a196d9..d4414ee 100644 --- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreController.java +++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreController.java @@ -47,12 +47,12 @@ public class StoreController { } @GetMapping("cm-history") - public List<MessageDTO> getAllConfigurationChanges() { + public List<Message> getAllConfigurationChanges() { return service.getAllMessages(); } @GetMapping("/less") - public List<MessageDTO> less(@RequestParam(value = "offset", required = false, defaultValue = "${spring.kafka.default-offset}") long offset) { + public List<Message> less(@RequestParam(value = "offset", required = false, defaultValue = "${spring.kafka.default-offset}") long offset) { return service.getLastMessages(offset); } 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 5fddff5..6bd8390 100644 --- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.java +++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/kafka/StoreService.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. @@ -28,6 +28,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.stereotype.Service; +import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.Collections; @@ -48,33 +49,33 @@ public class StoreService { this.consumerFactory = consumerFactory; } - List<MessageDTO> getAllMessages() { - List<MessageDTO> messages = new ArrayList<>(); - String clientID = Long.toString(Instant.now().getEpochSecond()); - try (Consumer<String, String> consumer = consumerFactory.createConsumer(clientID, clientID)) { + List<Message> getAllMessages() { + List<Message> messages = new ArrayList<>(); + String clientId = Long.toString(Instant.now().getEpochSecond()); + try (Consumer<String, String> consumer = consumerFactory.createConsumer(clientId, clientId)) { consumer.subscribe(TOPICS_TO_SUBSCRIBE); - ConsumerRecords<String, String> consumerRecords = consumer.poll(CONSUMING_DURATION_IN_MS); + ConsumerRecords<String, String> consumerRecords = pollConsumerRecords(consumer); consumerRecords.forEach( consumerRecord -> - messages.add(new MessageDTO(consumerRecord.timestamp(), consumerRecord.value()))); + messages.add(new Message(consumerRecord.timestamp(), consumerRecord.value()))); log.debug(String.format("consumed %d messages", consumerRecords.count())); - } + } return messages; } - List<MessageDTO> getLastMessages(long offset) { - List<MessageDTO> messages = new ArrayList<>(); + List<Message> getLastMessages(long offset) { + List<Message> messages = new ArrayList<>(); try (Consumer<String, String> consumer = createConsumer(offset)) { - ConsumerRecords<String, String> consumerRecords = consumer.poll(CONSUMING_DURATION_IN_MS); + ConsumerRecords<String, String> consumerRecords = pollConsumerRecords(consumer); consumerRecords.forEach(consumerRecord -> - messages.add(new MessageDTO(consumerRecord.timestamp(), consumerRecord.value()))); + messages.add(new Message(consumerRecord.timestamp(), consumerRecord.value()))); } return messages; } private Consumer<String, String> createConsumer(long offsetFromLastIndex) { - String clientID = Long.toString(Instant.now().getEpochSecond()); - Consumer<String, String> consumer = consumerFactory.createConsumer(clientID, clientID); + String clientId = Long.toString(Instant.now().getEpochSecond()); + Consumer<String, String> consumer = consumerFactory.createConsumer(clientId, clientId); consumer.subscribe(TOPICS_TO_SUBSCRIBE); seekConsumerTo(consumer, offsetFromLastIndex); return consumer; @@ -82,10 +83,14 @@ public class StoreService { private void seekConsumerTo(Consumer<String, String> consumer, long offsetFromLastIndex) { consumer.seekToEnd(consumer.assignment()); - consumer.poll(CONSUMING_DURATION_IN_MS); + pollConsumerRecords(consumer); TopicPartition topicPartition = consumer.assignment().iterator().next(); long topicCurrentSize = consumer.position(topicPartition); long indexToSeek = offsetFromLastIndex > topicCurrentSize ? 0 : topicCurrentSize - offsetFromLastIndex; consumer.seek(topicPartition, indexToSeek); } + + private ConsumerRecords<String, String> pollConsumerRecords(Consumer<String, String> consumer) { + return consumer.poll(Duration.ofMillis(CONSUMING_DURATION_IN_MS)); + } } diff --git a/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationTO.java b/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfiguration.java index e43ff69..51f31ae 100644 --- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationTO.java +++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfiguration.java @@ -25,7 +25,7 @@ import lombok.Getter; @Getter @AllArgsConstructor -public class NetconfConfigurationTO { +public class NetconfConfiguration { private String configuration; diff --git a/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationService.java b/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationService.java index 248aec4..8f6f0ba 100644 --- a/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationService.java +++ b/netconfsimulator/src/main/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationService.java @@ -64,8 +64,8 @@ public class NetconfConfigurationService { public String editCurrentConfiguration(MultipartFile newConfiguration) throws IOException, JNCException { Element configurationElement = convertMultipartToXmlElement(newConfiguration); configurationEditor.editConfig(configurationElement); - - LOGGER.debug("Loading new configuration: \n{}", configurationElement.toXMLString()); + String configurationXmlString = configurationElement.toXMLString(); + LOGGER.debug("Loading new configuration: \n{}", configurationXmlString); return CONFIGURATION_HAS_BEEN_ACTIVATED; } diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/EmbeddedKafkaConfig.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/EmbeddedKafkaConfig.java index 5ddf2b2..6d487b2 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/EmbeddedKafkaConfig.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/EmbeddedKafkaConfig.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. @@ -22,6 +22,7 @@ package org.onap.netconfsimulator.kafka; import java.util.Map; + import org.apache.kafka.clients.consumer.ConsumerConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -40,20 +41,20 @@ import static org.onap.netconfsimulator.kafka.StoreServiceTest.embeddedKafka; class EmbeddedKafkaConfig { @Bean - KafkaTemplate<String, String> kafkaTemplate(){ + KafkaTemplate<String, String> kafkaTemplate() { return new KafkaTemplate<>(producerFactory()); } @Bean @Autowired - ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(ConsumerFactory<String, String> consumerFactory){ + ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory(ConsumerFactory<String, String> consumerFactory) { ConcurrentKafkaListenerContainerFactory<String, String> containerFactory = new ConcurrentKafkaListenerContainerFactory<>(); containerFactory.setConsumerFactory(consumerFactory); return containerFactory; } @Bean - ConsumerFactory<String, String> consumerFactory(){ + ConsumerFactory<String, String> consumerFactory() { Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("sender", "false", embeddedKafka.getEmbeddedKafka()); consumerProperties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreControllerTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreControllerTest.java index 02eec12..bd6fd14 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreControllerTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreControllerTest.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. @@ -22,6 +22,7 @@ package org.onap.netconfsimulator.kafka; import java.time.Instant; import java.util.List; + import org.assertj.core.api.Assertions; import org.assertj.core.util.Lists; import org.junit.Test; @@ -39,9 +40,9 @@ public class StoreControllerTest { private static final String MESSAGE_2 = "message 2"; private static final String MESSAGE_1 = "message 1"; - private static final List<MessageDTO> ALL_MESSAGES = Lists.newArrayList(new MessageDTO(Instant.now().getEpochSecond(), MESSAGE_1), - new MessageDTO(Instant.now().getEpochSecond(), MESSAGE_2), - new MessageDTO(Instant.now().getEpochSecond(), MESSAGE_3)); + private static final List<Message> ALL_MESSAGES = Lists.newArrayList(new Message(Instant.now().getEpochSecond(), MESSAGE_1), + new Message(Instant.now().getEpochSecond(), MESSAGE_2), + new Message(Instant.now().getEpochSecond(), MESSAGE_3)); @Mock private StoreService service; @@ -54,33 +55,33 @@ public class StoreControllerTest { public void lessShouldTakeAllMessagesTest() { when(service.getLastMessages(3)).thenReturn(ALL_MESSAGES); - List<MessageDTO> lessResponse = storeController.less(3); + List<Message> lessResponse = storeController.less(3); assertResponseContainsExpectedMessages(lessResponse, 3, MESSAGE_1, MESSAGE_2, MESSAGE_3); } @Test public void lessShouldTakeTwoMessagesTest() { - when(service.getLastMessages(2)).thenReturn(Lists.newArrayList(new MessageDTO(Instant.now().getEpochSecond(), MESSAGE_1))); + when(service.getLastMessages(2)).thenReturn(Lists.newArrayList(new Message(Instant.now().getEpochSecond(), MESSAGE_1))); - List<MessageDTO> lessResult = storeController.less(2); + List<Message> lessResult = storeController.less(2); assertResponseContainsExpectedMessages(lessResult, 1, MESSAGE_1); } @Test - public void shouldGetAllMessages(){ + public void shouldGetAllMessages() { when(service.getAllMessages()).thenReturn(ALL_MESSAGES); - List<MessageDTO> allMsgResult = storeController.getAllConfigurationChanges(); + List<Message> allMsgResult = storeController.getAllConfigurationChanges(); assertResponseContainsExpectedMessages(allMsgResult, 3, MESSAGE_1, MESSAGE_2, MESSAGE_3); } - private void assertResponseContainsExpectedMessages(List<MessageDTO> actualMessages, int expectedMessageCount, String... expectedMessages){ - Assertions.assertThat(actualMessages.stream().map(MessageDTO::getConfiguration)) - .hasSize(expectedMessageCount) - .containsExactly(expectedMessages); + private void assertResponseContainsExpectedMessages(List<Message> actualMessages, int expectedMessageCount, String... expectedMessages) { + Assertions.assertThat(actualMessages.stream().map(Message::getConfiguration)) + .hasSize(expectedMessageCount) + .containsExactly(expectedMessages); } } diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreServiceTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreServiceTest.java index fd36116..fdba959 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreServiceTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/kafka/StoreServiceTest.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. @@ -59,38 +59,38 @@ public class StoreServiceTest { } @Test - public void testShouldReturnAllAvailableMessages(){ + public void testShouldReturnAllAvailableMessages() { - List<MessageDTO> actualMessages = service.getAllMessages(); + List<Message> actualMessages = service.getAllMessages(); assertResponseContainsExpectedMessages(actualMessages, 3, MESSAGE_1, MESSAGE_2, MESSAGE_3); } @Test - public void testShouldGetLastMessagesRespectingOffset(){ + public void testShouldGetLastMessagesRespectingOffset() { - List<MessageDTO> wantedLastMsg = service.getLastMessages(1L); + List<Message> wantedLastMsg = service.getLastMessages(1L); assertResponseContainsExpectedMessages(wantedLastMsg, 1, MESSAGE_3); } @Test - public void testShouldGetAll3Messages() { - List<MessageDTO> wantedLastMsgs = service.getLastMessages(3L); + public void testShouldGetAll3Messages() { + List<Message> wantedLastMsgs = service.getLastMessages(3L); assertResponseContainsExpectedMessages(wantedLastMsgs, 3, MESSAGE_1, MESSAGE_2, MESSAGE_3); } - private void prepareProducer(){ + private void prepareProducer() { kafkaTemplate.send("config", "message1"); kafkaTemplate.send("config", "message2"); kafkaTemplate.send("config", "message3"); } - private void assertResponseContainsExpectedMessages(List<MessageDTO> actualMessages, int expectedMessageCount, String... expectedMessages){ - assertThat(actualMessages.stream().map(MessageDTO::getConfiguration)) - .hasSize(expectedMessageCount) - .containsExactly(expectedMessages); + private void assertResponseContainsExpectedMessages(List<Message> actualMessages, int expectedMessageCount, String... expectedMessages) { + assertThat(actualMessages.stream().map(Message::getConfiguration)) + .hasSize(expectedMessageCount) + .containsExactly(expectedMessages); } } diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationReaderTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationReaderTest.java index a0a15b9..7095040 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationReaderTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationReaderTest.java @@ -65,7 +65,7 @@ class NetconfConfigurationReaderTest { } @Test - void properlyReadXML() throws IOException, JNCException { + void properlyReadXml() throws IOException, JNCException { when(netconfSession.getConfig()).thenReturn(nodeSet); when(nodeSet.toXMLString()).thenReturn(EXPECTED_STRING_XML); diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationServiceTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationServiceTest.java index 6da6572..f42ad84 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationServiceTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/configuration/NetconfConfigurationServiceTest.java @@ -28,8 +28,10 @@ import static org.mockito.MockitoAnnotations.initMocks; import com.tailf.jnc.Element; import com.tailf.jnc.JNCException; + import java.io.IOException; import java.nio.file.Files; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; @@ -49,11 +51,11 @@ class NetconfConfigurationServiceTest { @InjectMocks NetconfConfigurationService service; - private static String CURRENT_CONFIG_XML_STRING = - "<config xmlns=\"http://onap.org/pnf-simulator\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" - + " <itemValue1>100</itemValue1>\n" - + " <itemValue2>200</itemValue2>\n" - + "</config>\n"; + private static String CURRENT_CONFIG_XML_STRING = + "<config xmlns=\"http://onap.org/pnf-simulator\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" + + " <itemValue1>100</itemValue1>\n" + + " <itemValue2>200</itemValue2>\n" + + "</config>\n"; @BeforeEach void setUp() { @@ -71,16 +73,16 @@ class NetconfConfigurationServiceTest { } @Test - void testShouldThrowExceptionWhenCurrentConfigurationDoesNotExists() throws IOException, JNCException{ + void testShouldThrowExceptionWhenCurrentConfigurationDoesNotExists() throws IOException, JNCException { when(reader.getRunningConfig()).thenThrow(JNCException.class); assertThatThrownBy(() -> service.getCurrentConfiguration()).isInstanceOf(JNCException.class); } @Test - void testShouldEditConfigurationSuccessfully() throws IOException, JNCException{ + void testShouldEditConfigurationSuccessfully() throws IOException, JNCException { byte[] bytes = - Files.readAllBytes(ResourceUtils.getFile("classpath:updatedConfig.xml").toPath()); + Files.readAllBytes(ResourceUtils.getFile("classpath:updatedConfig.xml").toPath()); MockMultipartFile editConfigXmlContent = new MockMultipartFile("editConfigXml", bytes); ArgumentCaptor<Element> elementCaptor = ArgumentCaptor.forClass(Element.class); doNothing().when(editor).editConfig(elementCaptor.capture()); @@ -93,7 +95,7 @@ class NetconfConfigurationServiceTest { @Test void testShouldRaiseExceptionWhenMultipartFileIsInvalidXmlFile() throws IOException { byte[] bytes = - Files.readAllBytes(ResourceUtils.getFile("classpath:invalidXmlFile.xml").toPath()); + Files.readAllBytes(ResourceUtils.getFile("classpath:invalidXmlFile.xml").toPath()); MockMultipartFile editConfigXmlContent = new MockMultipartFile("editConfigXml", bytes); assertThatThrownBy(() -> service.editCurrentConfiguration(editConfigXmlContent)).isInstanceOf(JNCException.class); diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/model/NetconfModelLoaderServiceTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/model/NetconfModelLoaderServiceTest.java index a10876b..8d26881 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/model/NetconfModelLoaderServiceTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/netconfcore/model/NetconfModelLoaderServiceTest.java @@ -61,7 +61,6 @@ class NetconfModelLoaderServiceTest { @Test void shouldSendMultipartToServer() throws IOException { //given - String loadModelAddress = modelLoaderService.getBackendAddress(); makeMockClientReturnStatusOk(httpClient, HttpPost.class); ArgumentCaptor<HttpPost> postArgumentCaptor = ArgumentCaptor.forClass(HttpPost.class); MultipartFile yangMmodel = mock(MultipartFile.class); @@ -69,6 +68,7 @@ class NetconfModelLoaderServiceTest { String moduleName = "moduleName"; when(yangMmodel.getInputStream()).thenReturn(getEmptyImputStream()); when(initialConfig.getInputStream()).thenReturn(getEmptyImputStream()); + String loadModelAddress = modelLoaderService.getBackendAddress(); //when LoadModelResponse response = modelLoaderService.loadYangModel(yangMmodel, initialConfig, moduleName); @@ -86,9 +86,9 @@ class NetconfModelLoaderServiceTest { void shouldSendDeleteRequestToServer() throws IOException { //given String yangModelName = "sampleModel"; - String deleteModelAddress = modelLoaderService.getDeleteAddress(yangModelName); makeMockClientReturnStatusOk(httpClient, HttpDelete.class); ArgumentCaptor<HttpDelete> deleteArgumentCaptor = ArgumentCaptor.forClass(HttpDelete.class); + String deleteModelAddress = modelLoaderService.getDeleteAddress(yangModelName); //when LoadModelResponse response = modelLoaderService.deleteYangModel(yangModelName); diff --git a/netconfsimulator/src/test/java/org/onap/netconfsimulator/websocket/message/NetconfMessageListenerTest.java b/netconfsimulator/src/test/java/org/onap/netconfsimulator/websocket/message/NetconfMessageListenerTest.java index bb040d1..c6e58c9 100644 --- a/netconfsimulator/src/test/java/org/onap/netconfsimulator/websocket/message/NetconfMessageListenerTest.java +++ b/netconfsimulator/src/test/java/org/onap/netconfsimulator/websocket/message/NetconfMessageListenerTest.java @@ -69,5 +69,7 @@ class NetconfMessageListenerTest { doThrow(new EncodeException("","")).when(remoteEndpoint).sendObject(any(KafkaMessage.class)); netconfMessageListener.onMessage(KAFKA_RECORD); + + verify(remoteEndpoint).sendObject(any(KafkaMessage.class)); } } diff --git a/pnfsimulator/Dockerfile b/pnfsimulator/Dockerfile index 7cadcf4..52e507c 100644 --- a/pnfsimulator/Dockerfile +++ b/pnfsimulator/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/openjdk:8-jre-alpine +FROM docker.io/openjdk:11-jre-slim ARG VERSION=${version} diff --git a/pnfsimulator/Makefile b/pnfsimulator/Makefile new file mode 100644 index 0000000..58de699 --- /dev/null +++ b/pnfsimulator/Makefile @@ -0,0 +1,13 @@ +all: start + +.PHONY: start + +start: + @echo "##### Start PNF simulator #####" + docker-compose up -d + @echo "##### DONE #####" + +stop: + @echo "##### Stop PNF simulator #####" + docker-compose down + @echo "##### DONE #####" diff --git a/pnfsimulator/integration/pom.xml b/pnfsimulator/integration/pom.xml index e411735..5b8e738 100644 --- a/pnfsimulator/integration/pom.xml +++ b/pnfsimulator/integration/pom.xml @@ -39,8 +39,8 @@ </repositories> <properties> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> + <maven.compiler.source>11</maven.compiler.source> + <maven.compiler.target>11</maven.compiler.target> </properties> <dependencies> diff --git a/pnfsimulator/pom.xml b/pnfsimulator/pom.xml index 251feb2..436571d 100644 --- a/pnfsimulator/pom.xml +++ b/pnfsimulator/pom.xml @@ -37,8 +37,8 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> + <maven.compiler.source>11</maven.compiler.source> + <maven.compiler.target>11</maven.compiler.target> <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format> <simulator.main.class>org.onap.pnfsimulator.Main</simulator.main.class> <docker.image.tag>latest</docker.image.tag> diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java index 23b1c21..ff85367 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java @@ -24,12 +24,14 @@ import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Builder; import lombok.Getter; import lombok.Setter; +import lombok.ToString; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Field; @Builder @Getter @Setter +@ToString(exclude = "incrementValue") public class EventData { @Id private String id; @@ -62,15 +64,4 @@ public class EventData { this.keywords = keywords; this.incrementValue = incrementValue; } - - @Override - public String toString() { - return "EventData{" - + "id='" + id + '\'' - + ", template='" + template + '\'' - + ", patched='" + patched + '\'' - + ", input='" + input + '\'' - + ", keywords='" + keywords + '\'' - + '}'; - } } 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 3647ecc..023b163 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java @@ -94,16 +94,20 @@ public class SimulatorController { this.eventDataService = eventDataService; } + /** + * @deprecated + */ @PostMapping("test") @Deprecated - public ResponseEntity test(@Valid @RequestBody SimulatorRequest simulatorRequest) { + public ResponseEntity<Map<String,Object>> test(@Valid @RequestBody SimulatorRequest simulatorRequest) { MDC.put("test", "test"); - LOGGER.info(ENTRY, simulatorRequest.toString()); + String simulatorRequestString = simulatorRequest.toString(); + LOGGER.info(ENTRY, simulatorRequestString); return buildResponse(OK, ImmutableMap.of(MESSAGE, "message1234")); } @PostMapping(value = "start") - public ResponseEntity start(@RequestHeader HttpHeaders headers, + public ResponseEntity<Map<String,Object>> start(@RequestHeader HttpHeaders headers, @Valid @RequestBody SimulatorRequest triggerEventRequest) { logContextHeaders(headers, "/simulator/start"); LOGGER.info(ENTRY, "Simulator started"); @@ -138,9 +142,12 @@ public class SimulatorController { } } + /** + * @deprecated + */ @GetMapping("all-events") @Deprecated - public ResponseEntity 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())); @@ -151,33 +158,34 @@ public class SimulatorController { } @GetMapping("config") - public ResponseEntity getConfig() { + public ResponseEntity<Map<String,Object>> getConfig() { SimulatorConfig configToGet = simulatorService.getConfiguration(); return buildResponse(OK, ImmutableMap.of("simulatorConfig", configToGet)); } @PutMapping("config") - public ResponseEntity 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 cancelEvent(@PathVariable String jobName) throws SchedulerException { - LOGGER.info(ENTRY, "Cancel called on {}.", replaceBreakingCharacters(jobName)); + 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); return createCancelEventResponse(isCancelled); } @PostMapping("cancel") - public ResponseEntity 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 sendEventDirectly(@RequestHeader HttpHeaders headers, @Valid @RequestBody FullEvent event) + 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"); @@ -189,7 +197,7 @@ public class SimulatorController { return jobName.replaceAll(BREAKING_CHARACTER_REGEX, "_"); } - private ResponseEntity processRequest(SimulatorRequest triggerEventRequest) + private ResponseEntity<Map<String,Object>> processRequest(SimulatorRequest triggerEventRequest) throws IOException, SchedulerException, GeneralSecurityException { String jobName = simulatorService.triggerEvent(triggerEventRequest); @@ -197,7 +205,7 @@ public class SimulatorController { return buildResponse(OK, ImmutableMap.of(MESSAGE, "Request started", "jobName", jobName)); } - private ResponseEntity 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)); @@ -212,7 +220,7 @@ public class SimulatorController { MDC.put(SERVICE_NAME, serviceName); } - private ResponseEntity 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/rest/util/ResponseBuilder.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/ResponseBuilder.java index 5fca25a..1fdd7cf 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/ResponseBuilder.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/ResponseBuilder.java @@ -50,7 +50,7 @@ public class ResponseBuilder { return this; } - public ResponseEntity build() { + public ResponseEntity<Map<String,Object>> build() { if (body.isEmpty()) { return ResponseEntity.status(httpStatus).build(); diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java index 51e0c1f..ac80647 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java @@ -24,9 +24,11 @@ import com.google.gson.JsonElement; import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; + import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; + import org.springframework.stereotype.Component; @Component @@ -43,14 +45,14 @@ public class KeywordsHandler { public JsonElement substituteKeywords(JsonElement jsonBody, String jobId) { int counter = incrementProvider.getAndIncrement(jobId); try ( - JsonReader reader = new JsonReader(new StringReader(jsonBody.toString())); - StringWriter stringWriter = new StringWriter(); - JsonWriter jsonWriter = new JsonWriter(stringWriter); + JsonReader reader = new JsonReader(new StringReader(jsonBody.toString())); + StringWriter stringWriter = new StringWriter(); + JsonWriter jsonWriter = new JsonWriter(stringWriter); ) { modify(reader, jsonWriter, counter); return new Gson().fromJson(stringWriter.getBuffer().toString(), JsonElement.class); } catch (IOException e) { - throw new RuntimeException(e); + throw new KeywordsHandlerException(e); } } diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandlerException.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandlerException.java new file mode 100644 index 0000000..9685bc3 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandlerException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * 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.simulator; + +public class KeywordsHandlerException extends RuntimeException { + + public KeywordsHandlerException(Throwable cause) { + super(cause); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslAuthenticationHelper.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslAuthenticationHelper.java index ee5fdb7..1887d37 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslAuthenticationHelper.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslAuthenticationHelper.java @@ -20,6 +20,9 @@ package org.onap.pnfsimulator.simulator.client.utils.ssl; import java.io.Serializable; + +import lombok.Getter; +import lombok.Setter; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Primary; @@ -29,6 +32,8 @@ import org.springframework.stereotype.Component; @ConfigurationProperties(prefix = "ssl") @RefreshScope @Primary +@Getter +@Setter public class SslAuthenticationHelper implements Serializable { private boolean clientCertificateEnabled; @@ -36,44 +41,4 @@ public class SslAuthenticationHelper implements Serializable { private String clientCertificatePassword; private String trustStoreDir; private String trustStorePassword; - - public boolean isClientCertificateEnabled() { - return clientCertificateEnabled; - } - - public void setClientCertificateEnabled(boolean clientCertificateEnabled) { - this.clientCertificateEnabled = clientCertificateEnabled; - } - - public String getClientCertificateDir() { - return clientCertificateDir; - } - - public void setClientCertificateDir(String clientCertificateDir) { - this.clientCertificateDir = clientCertificateDir; - } - - public String getClientCertificatePassword() { - return clientCertificatePassword; - } - - public void setClientCertificatePassword(String clientCertificatePassword) { - this.clientCertificatePassword = clientCertificatePassword; - } - - public String getTrustStoreDir() { - return trustStoreDir; - } - - public void setTrustStoreDir(String trustStoreDir) { - this.trustStoreDir = trustStoreDir; - } - - public String getTrustStorePassword() { - return trustStorePassword; - } - - public void setTrustStorePassword(String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } } diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java index 91c5a67..0080813 100644 --- a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java @@ -20,12 +20,6 @@ package org.onap.pnfsimulator.template; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.stream.Stream; - import org.bson.json.JsonParseException; import org.onap.pnfsimulator.db.Storage; import org.onap.pnfsimulator.filesystem.WatcherEventProcessor; @@ -35,6 +29,12 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + @Service public class FsToDbTemplateSynchronizer { @@ -66,7 +66,7 @@ public class FsToDbTemplateSynchronizer { WatcherEventProcessor.MODIFIED.processEvent(path, storage); } catch (IOException | JsonParseException e) { LOGGER - .error("Cannot synchronize template: {}", path.getFileName().toString(), e); + .error("Cannot synchronize template: {}", path.getFileName(), e); } }); } diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeywordTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeywordTest.java new file mode 100644 index 0000000..6477fbf --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeywordTest.java @@ -0,0 +1,48 @@ +/*- + * ============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.simulator.keywords; + + +import io.vavr.Tuple1; +import org.junit.jupiter.api.Test; + +import static org.junit.Assert.assertEquals; + +class TwoParameterKeywordTest { + @Test + public void whenGivenKeywordShouldReturnTwoParameterKeywordObjectWithParsedValues() { + //given + final String expectedName = "TEST"; + final Integer expectedParam1 = 123; + final Integer expectedParam2 = 456; + + String keyword = "#" + expectedName + "(" + expectedParam1 + "," + expectedParam2 + ")"; + + //when + Tuple1<TwoParameterKeyword> keywordTuple = TwoParameterKeyword.twoParameterKeyword(keyword); + TwoParameterKeyword twoParameterKeyword = keywordTuple._1(); + + //then + assertEquals(twoParameterKeyword.getName(), expectedName); + assertEquals(twoParameterKeyword.getAdditionalParameter1(), expectedParam1); + assertEquals(twoParameterKeyword.getAdditionalParameter2(), expectedParam2); + } +}
\ No newline at end of file @@ -46,8 +46,8 @@ <releaseNexusPath>/content/repositories/releases/</releaseNexusPath> <stagingNexusPath>/content/repositories/staging/</stagingNexusPath> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>1.8</maven.compiler.source> - <maven.compiler.target>1.8</maven.compiler.target> + <maven.compiler.source>11</maven.compiler.source> + <maven.compiler.target>11</maven.compiler.target> <docker-maven-plugin.version>0.31.0</docker-maven-plugin.version> <skipDockerPush>true</skipDockerPush> <sonar.coverage.jacoco.xmlReportPaths>${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml @@ -86,6 +86,7 @@ <quartz-jobs.version>2.2.1</quartz-jobs.version> <guava.version>21.0</guava.version> <logback-classic.version>1.2.3</logback-classic.version> + <sonar-maven-plugin.version>3.7.0.1746</sonar-maven-plugin.version> <!-- TEST DEPENDENCIES VERSION --> @@ -104,9 +105,12 @@ <dependencyManagement> <dependencies> - <!-- Compile DEPENDENCIES --> - + <dependency> + <groupId>org.sonarsource.scanner.maven</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>${sonar-maven-plugin.version}</version> + </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> @@ -326,6 +330,17 @@ </profiles> <build> + <pluginManagement> + <plugins> + <!-- To run SonarQube locally --> + <plugin> + <groupId>org.sonarsource.scanner.maven</groupId> + <artifactId>sonar-maven-plugin</artifactId> + <version>${sonar-maven-plugin.version}</version> + </plugin> + </plugins> + </pluginManagement> + <plugins> <plugin> <artifactId>maven-checkstyle-plugin</artifactId> diff --git a/sanitycheck/Makefile b/sanitycheck/Makefile new file mode 100644 index 0000000..37f2669 --- /dev/null +++ b/sanitycheck/Makefile @@ -0,0 +1,40 @@ +all: start + +.PHONY: start + +build: + @echo "##### build (dmaap sim) #####" + make -C dmaap-simulator build + @echo "##### DONE #####" + +start: build + @echo "##### start (dmaap sim,ves,pnf sim) #####" + make -C ves start + make -C ../pnfsimulator start + @echo "##### DONE #####" + +stop: + @echo "##### Stop (dmaap sim,ves,pnf sim) #####" + make -C ves stop + make -C ../pnfsimulator stop + @echo "##### DONE #####" + +generate-event: + @echo "##### Trigger PNF Simulator to generate event #####" + curl -X POST http://localhost:5000/simulator/event -d @events/eventToVes.json --header "Content-Type: application/json" + @echo "\n##### DONE #####" + +reconfigure-ves-url: + @echo "##### Change VES address configuration in PNF Simulator #####" + curl -X PUT http://localhost:5000/simulator/config -d @events/vesAddressConfiguration.json --header "Content-Type: application/json" + @echo "\n##### DONE #####" + +generate-multiple-events: + @echo "\n##### Trigger PNF Simulator to generate multiple events #####" + curl -X POST http://localhost:5000/simulator/start -d @events/fewEventsToVes.json --header "Content-Type: application/json" + @echo "\n##### DONE #####" + +check-dmaap: + @echo "##### Check dmaap simulator for collected events #####" + make -C dmaap-simulator get-data + @echo "\n##### DONE #####"
\ No newline at end of file diff --git a/sanitycheck/README.md b/sanitycheck/README.md new file mode 100644 index 0000000..9fb4929 --- /dev/null +++ b/sanitycheck/README.md @@ -0,0 +1,52 @@ +### Run test case pnfsimulator -> ves collector -> dmaap simulator + +### Prerequisites +* Check your docker network ip: +``` +ip a | grep docker0 | grep inet +``` +If the IP address is different than 172.17.0.1/16: +inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 + +You have to change the IP address in file events/vesAddressConfiguration.json +``` +{ + "vesServerUrl": "http://<IP_Address>:8080/eventListener/v7" +} +``` +and in file events/eventToVes.json + +``` +{ +"vesServerUrl": "http://<IP_Address>:8080/eventListener/v7", +"event": { ... +``` +### 1. Build Projects +``` +make start +``` +### 2. Send one event +``` +make generate-event +``` +### 2.1 Check dmaap sim +``` +make check-dmaap +``` +### 3. Send few events: +### 3.1 Reconfigure ves url +``` +make reconfigure-ves-url +``` +### 3.2 Send events +``` +make generate-multiple-events +``` +### 3.3 Check dmaap sim +``` +make check-dmaap +``` +### 4. Clear environment +``` +make stop +``` diff --git a/sanitycheck/dmaap-simulator/Dockerfile b/sanitycheck/dmaap-simulator/Dockerfile new file mode 100644 index 0000000..f84cac2 --- /dev/null +++ b/sanitycheck/dmaap-simulator/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3 +WORKDIR /application +COPY ./simulator.py ./ +COPY ./requirements.txt ./ +RUN pip install -r ./requirements.txt +ENV FLASK_APP=./simulator.py +CMD ["python", "./simulator.py"] diff --git a/sanitycheck/dmaap-simulator/Makefile b/sanitycheck/dmaap-simulator/Makefile new file mode 100644 index 0000000..af8f162 --- /dev/null +++ b/sanitycheck/dmaap-simulator/Makefile @@ -0,0 +1,23 @@ +all: build + +.PHONY: build + +build: + @echo "##### Build dmaap simulator image #####" + docker build . -t dmaap-simulator + @echo "##### DONE #####" + +start: + @echo "##### Start dmaap simulator #####" + docker run -d -p 3904:3904 --name dmaap-simulator dmaap-simulator + @echo "##### DONE #####" + +stop: + @echo "##### Stop dmaap simulator #####" + docker rm -f dmaap-simulator + @echo "##### DONE #####" + +get-data: + @echo "##### Get data fetched by dmaap-simulator #####\n" + curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:3904/events + @echo "\n\n##### DONE #####" diff --git a/sanitycheck/dmaap-simulator/README.md b/sanitycheck/dmaap-simulator/README.md new file mode 100644 index 0000000..c06afdf --- /dev/null +++ b/sanitycheck/dmaap-simulator/README.md @@ -0,0 +1,23 @@ +DMaaP simulator +--------------- + + +### Build an image +``` +make build +``` + +### Start +``` +make start +``` + +### Stop +``` +make stop +``` + +### Get fetched events +``` +make get-data +``` diff --git a/sanitycheck/dmaap-simulator/requirements.txt b/sanitycheck/dmaap-simulator/requirements.txt new file mode 100644 index 0000000..a6d2d3a --- /dev/null +++ b/sanitycheck/dmaap-simulator/requirements.txt @@ -0,0 +1,6 @@ +Click==7.0 +Flask==1.1.1 +itsdangerous==1.1.0 +Jinja2==2.10.3 +MarkupSafe==1.1.1 +Werkzeug==0.16.0 diff --git a/sanitycheck/dmaap-simulator/simulator.py b/sanitycheck/dmaap-simulator/simulator.py new file mode 100644 index 0000000..3437442 --- /dev/null +++ b/sanitycheck/dmaap-simulator/simulator.py @@ -0,0 +1,47 @@ +import json +import logging as sys_logging + +from flask import Flask, request, logging +app = Flask(__name__) + +sys_logging.basicConfig(level=sys_logging.DEBUG) +logger = logging.create_logger(app) +events = [] + +@app.route("/events/unauthenticated.VES_NOTIFICATION_OUTPUT", methods=['POST']) +def event_ves_notification_output(): + return handle_new_event(request) + +@app.route("/events/unauthenticated.SEC_FAULT_OUTPUT", methods=['POST']) +def event_sec_fault_output(): + return handle_new_event(request) + +def handle_new_event(http_request): + receive_events = decode_request_data(http_request.data) + for event in receive_events: + events.append(json.loads(event)) + return {}, 200 + +@app.route("/events", methods=['GET']) +def get_events(): + return json.dumps(events), 200 + +def decode_request_data(request_data): + data = request_data.decode("utf-8") + receive_events = data.split("\n") + receive_events = receive_events[:-1] + logger.info("received events: " + str(receive_events)) + correct_events = [] + for event in receive_events: + logger.info("received event: " + str(event)) + correct_events.append(get_correct_json(event)) + return correct_events + +def get_correct_json(incorrect_json): + json_start_position = incorrect_json.find("{") + correct_json = incorrect_json[json_start_position:] + correct_json = correct_json.replace("\r", "").replace("\t", "").replace(" ", "") + return correct_json + +if __name__ == "__main__": + app.run(host='0.0.0.0', port=3904) diff --git a/sanitycheck/events/eventToVes.json b/sanitycheck/events/eventToVes.json new file mode 100644 index 0000000..7299306 --- /dev/null +++ b/sanitycheck/events/eventToVes.json @@ -0,0 +1,37 @@ +{ + "vesServerUrl": "http://172.17.0.1:8080/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" + } + } + } + } +} diff --git a/sanitycheck/events/fewEventsToVes.json b/sanitycheck/events/fewEventsToVes.json new file mode 100644 index 0000000..9733469 --- /dev/null +++ b/sanitycheck/events/fewEventsToVes.json @@ -0,0 +1,32 @@ +{ + "simulatorParams": { + "repeatCount": 4, + "repeatInterval": 1 + }, + "templateName": "notification.json", + "patch": { + "event": { + "commonEventHeader": { + "domain": "notification", + "eventName": "vFirewallBroadcastPackets", + "eventId": "#RandomString(10)", + "priority": "Normal", + "reportingEntityName": "myVNF", + "sequence": 1, + "sourceName": "ClosedLoopVNF", + "startEpochMicrosec": 1531616794, + "lastEpochMicrosec": 1531719042, + "vesEventListenerVersion": "7.0.1", + "version": "4.0.1" + } + } + }, + "variables": { + "dN": "NRNB=5, NRCEL=1234", + "dn": "Test_dn", + "attributeList": { + "threshXHighQ": "50", + "threshXHighP": "52" + } + } +} diff --git a/sanitycheck/events/vesAddressConfiguration.json b/sanitycheck/events/vesAddressConfiguration.json new file mode 100644 index 0000000..9c6aa22 --- /dev/null +++ b/sanitycheck/events/vesAddressConfiguration.json @@ -0,0 +1,3 @@ +{ + "vesServerUrl": "http://172.17.0.1:8080/eventListener/v7" +} diff --git a/sanitycheck/ves/Makefile b/sanitycheck/ves/Makefile new file mode 100644 index 0000000..4fe5e4b --- /dev/null +++ b/sanitycheck/ves/Makefile @@ -0,0 +1,23 @@ +all: start + +.PHONY: start + +start: + @echo "##### Start VES with DMAAP simulator #####" + docker-compose up -d + @echo "##### DONE #####" + +stop: + @echo "##### Stop VES with DMAAP simulator #####" + docker-compose down + @echo "##### DONE #####" + +health-check: + @echo "##### Health check #####\n" + + @echo "##### DMAAP simulator is ready #####\n" + curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:3904/events + + @echo "\n\n##### VES is ready #####\n" + curl -i -H "Accept: application/json" -H "Content-Type: application/json" -X GET GET http://localhost:8080/healthcheck + @echo "\n\n##### DONE #####" diff --git a/sanitycheck/ves/README.md b/sanitycheck/ves/README.md new file mode 100644 index 0000000..29309a4 --- /dev/null +++ b/sanitycheck/ves/README.md @@ -0,0 +1,21 @@ +VES with DMAAP simulator +------------------------ + +### Prerequisites +* DMaaP Simulator image available. + +See README.md in dmaap-simulator directory + +### Start +``` +make start +``` + +### Health check +``` +make health-check +``` + +### Stop +``` +make stop
\ No newline at end of file diff --git a/sanitycheck/ves/docker-compose.yml b/sanitycheck/ves/docker-compose.yml new file mode 100644 index 0000000..d9666d8 --- /dev/null +++ b/sanitycheck/ves/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3' +services: + ves: + container_name: ves + image: nexus3.onap.org:10003/onap/org.onap.dcaegen2.collectors.ves.vescollector:latest + ports: + - "8080:8080" + - "8443:8443" + networks: + - vesnetwork + onap-dmaap: + container_name: dmaap + image: dmaap-simulator + ports: + - "3904:3904" + networks: + - vesnetwork +networks: + vesnetwork: + driver: bridge |