diff options
Diffstat (limited to 'pnfsimulator/src')
98 files changed, 7544 insertions, 0 deletions
diff --git a/pnfsimulator/src/assembly/resources.xml b/pnfsimulator/src/assembly/resources.xml new file mode 100644 index 0000000..35dd3b2 --- /dev/null +++ b/pnfsimulator/src/assembly/resources.xml @@ -0,0 +1,57 @@ +<!-- + ============LICENSE_START======================================================= + Simulator + ================================================================================ + Copyright (C) 2019 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========================================================= + --> + +<assembly> + <id>resources</id> + <formats> + <format>zip</format> + </formats> + + <fileSets> + <fileSet> + <includes> + <include>simulator.sh</include> + </includes> + <lineEnding>unix</lineEnding> + <fileMode>0755</fileMode> + </fileSet> + <fileSet> + <includes> + <include>docker-compose.yml</include> + </includes> + <lineEnding>unix</lineEnding> + <fileMode>0644</fileMode> + </fileSet> + <fileSet> + <directory>config</directory> + <outputDirectory>config</outputDirectory> + <includes> + <include>**/*</include> + </includes> + </fileSet> + <fileSet> + <directory>deployment</directory> + <outputDirectory>deployment</outputDirectory> + <includes> + <include>**/*</include> + </includes> + </fileSet> + </fileSets> +</assembly> diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java new file mode 100644 index 0000000..e0eace2 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/Main.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import javax.annotation.PostConstruct; + +import org.onap.pnfsimulator.filesystem.WatcherService; +import org.onap.pnfsimulator.template.FsToDbTemplateSynchronizer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; + +@SpringBootApplication +@EnableAsync +public class Main { + + private final WatcherService watcherService; + private final FsToDbTemplateSynchronizer fsToDbTemplateSynchronizer; + + @Autowired + public Main(WatcherService watcherService, + FsToDbTemplateSynchronizer fsToDbTemplateSynchronizer) { + this.watcherService = watcherService; + this.fsToDbTemplateSynchronizer = fsToDbTemplateSynchronizer; + } + + public static void main(String[] args) { + SpringApplication.run(Main.class, args); + } + + @PostConstruct + public void createWatchers() { + fsToDbTemplateSynchronizer.synchronize(); + watcherService.createWatcher(); + } +} + + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/SwaggerConfig.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/SwaggerConfig.java new file mode 100644 index 0000000..6e0e18e --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/SwaggerConfig.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableConfigurationProperties(SSLAuthenticationHelper.class) +@EnableSwagger2 +public class SwaggerConfig { + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.onap.pnfsimulator")) + .paths(PathSelectors.any()) + .build(); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Row.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Row.java new file mode 100644 index 0000000..f9a167b --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Row.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.db; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Field; + +public abstract class Row { + @Id + @Field("_id") + protected String id; + + public String getId() { + return id; + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Storage.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Storage.java new file mode 100644 index 0000000..ad98ce0 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/db/Storage.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.db; + +import com.google.gson.JsonObject; + +import java.util.List; +import java.util.Optional; + +public interface Storage<T extends Row> { + + List<T> getAll(); + + Optional<T> get(String rowId); + + void persist(T row); + + boolean tryPersistOrOverwrite(T row, boolean overwrite); + + void delete(String rowId); + + List<String> getIdsByContentCriteria(JsonObject queryJson); +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java new file mode 100644 index 0000000..23b1c21 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventData.java @@ -0,0 +1,76 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.event; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Field; + +@Builder +@Getter +@Setter +public class EventData { + @Id + private String id; + + @Field("template") + @JsonInclude + private String template; + + @Field("patched") + @JsonInclude + private String patched; + + @Field("input") + @JsonInclude + private String input; + + @Field("keywords") + @JsonInclude + private String keywords; + + @Field("incrementValue") + @JsonInclude + private int incrementValue; + + protected EventData(String id, String template, String patched, String input, String keywords, int incrementValue) { + this.id = id; + this.template = template; + this.patched = patched; + this.input = input; + 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/event/EventDataRepository.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventDataRepository.java new file mode 100644 index 0000000..d1a66ab --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventDataRepository.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.event; + +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface EventDataRepository extends MongoRepository<EventData, String> { +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventDataService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventDataService.java new file mode 100644 index 0000000..3568f01 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/event/EventDataService.java @@ -0,0 +1,63 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.event; + +import com.google.gson.JsonObject; +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class EventDataService { + private final EventDataRepository repository; + + @Autowired + public EventDataService(EventDataRepository repository) { + this.repository = repository; + } + + private EventData persistEventData(String templateString, String patchedString, String inputString, String keywordsString) { + EventData eventData = EventData.builder() + .template(templateString) + .patched(patchedString) + .input(inputString) + .keywords(keywordsString) + .build(); + return repository.save(eventData); + } + + public EventData persistEventData(JsonObject templateJson, JsonObject patchedJson, JsonObject inputJson, + JsonObject keywordsJson) { + return persistEventData(templateJson.toString(), + patchedJson.toString(), + inputJson.toString(), + keywordsJson.toString()); + } + + public List<EventData> getAllEvents() { + return repository.findAll(); + } + + public Optional<EventData> getById(String id) { + return repository.findById(id); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherConfig.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherConfig.java new file mode 100644 index 0000000..3535e33 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherConfig.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@Configuration +public class WatcherConfig { + + @Bean + public TaskExecutor watcherTaskExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + executor.setThreadNamePrefix("pnfsimulator_fs_watcher"); + executor.initialize(); + return executor; + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessor.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessor.java new file mode 100644 index 0000000..56a5696 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessor.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchEvent.Kind; +import java.time.Instant; +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import lombok.extern.slf4j.Slf4j; +import org.bson.json.JsonParseException; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.template.Template; +import org.bson.Document; + +@Slf4j +public enum WatcherEventProcessor { + CREATED(StandardWatchEventKinds.ENTRY_CREATE) { + @Override + public void processEvent(Path path, Storage<Template> storage) throws IOException { + String content = getContent(path); + String fileName = path.getFileName().toString(); + Document documentsContent = Document.parse(content); + storage.persist(new Template(fileName, documentsContent, Instant.now().getNano())); + log.info("DB record created for template: " + fileName); + } + }, + MODIFIED(StandardWatchEventKinds.ENTRY_MODIFY) { + @Override + public void processEvent(Path path, Storage<Template> storage) throws IOException { + String fileName = path.getFileName().toString(); + String content = getContent(path); + Document documentsContent = Document.parse(content); + Template template = storage.get(fileName).orElse(new Template(fileName, documentsContent, Instant.now().getNano())); + template.setContent(documentsContent); + storage.persist(template); + log.info("DB record modified for template: " + fileName); + } + }, + DELETED(StandardWatchEventKinds.ENTRY_DELETE) { + @Override + public void processEvent(Path path, Storage<Template> storage) { + String fileName = path.getFileName().toString(); + storage.delete(fileName); + log.info("DB record deleted for template: " + fileName); + } + }; + + private final Kind<Path> pathKind; + + String getContent(Path path) throws IOException { + try (Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)) { + return lines.collect(Collectors.joining(System.lineSeparator())); + } catch (IOException e) { + log.error("Could not get content due to: " + e.getMessage() + " " + e.getCause(), e); + throw e; + } + } + + WatcherEventProcessor(Kind<Path> pathKind) { + this.pathKind = pathKind; + } + + public abstract void processEvent(Path templateName, Storage<Template> storage) throws IOException; + + static void process(WatchEvent<?> event, Storage<Template> storage, Path templatesDir) { + Optional<WatcherEventProcessor> watcherEventProcessor = getWatcherEventProcessor(event); + watcherEventProcessor.ifPresent(processor -> { + try { + final Path templatePath = templatesDir.resolve((Path) event.context()); + processor.processEvent(templatePath, storage); + } catch (IOException e) { + log.error("Error during processing DB record for template.", e); + } catch (JsonParseException e) { + log.error("Invalid JSON format provided for template.", e); + } + }); + } + + private static Optional<WatcherEventProcessor> getWatcherEventProcessor(WatchEvent<?> event) { + return Arrays.stream(values()).filter(value -> value.pathKind.equals(event.kind())).findFirst(); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherService.java new file mode 100644 index 0000000..26b684d --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherService.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.task.TaskExecutor; +import org.springframework.stereotype.Service; + +@Service +public class WatcherService { + + private TaskExecutor taskExecutor; + private ApplicationContext applicationContext; + + @Autowired + public WatcherService(ApplicationContext applicationContext, TaskExecutor taskExecutor) { + this.taskExecutor = taskExecutor; + this.applicationContext = applicationContext; + } + + public void createWatcher() { + taskExecutor.execute(applicationContext.getBean(WatcherThread.class)); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherThread.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherThread.java new file mode 100644 index 0000000..a202b1f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/filesystem/WatcherThread.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.nio.file.WatchKey; +import java.nio.file.WatchService; +import lombok.extern.slf4j.Slf4j; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.template.Template; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class WatcherThread implements Runnable { + + private final WatchService watchService; + private final Storage<Template> storage; + private final Path templatesDir; + + WatcherThread(String templatesDir, WatchService watchService, Storage<Template> storage) throws IOException { + this.watchService = watchService; + this.storage = storage; + this.templatesDir = Paths.get(templatesDir); + registerDirectory(this.templatesDir); + } + + @Autowired + public WatcherThread(@Value("${templates.dir}") String templatesDir, Storage<Template> storage) throws IOException { + this(templatesDir, FileSystems.getDefault().newWatchService(), storage); + } + + private void registerDirectory(Path path) throws IOException { + path.register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_DELETE, + StandardWatchEventKinds.ENTRY_MODIFY); + } + + @Override + public void run() { + while (true) { + WatchKey key; + try { + key = watchService.take(); + for (WatchEvent<?> event : key.pollEvents()) { + WatcherEventProcessor.process(event, storage, templatesDir); + } + key.reset(); + } catch (InterruptedException e) { + log.error("Watch service interrupted.", e.getMessage()); + Thread.currentThread().interrupt(); + return; + } + + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/logging/MDCVariables.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/logging/MDCVariables.java new file mode 100644 index 0000000..5678f4f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/logging/MDCVariables.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.logging; + +public final class MDCVariables { + + public static final String X_ONAP_REQUEST_ID = "X-ONAP-RequestID"; + public static final String X_INVOCATION_ID = "X-InvocationID"; + public static final String REQUEST_ID = "RequestID"; + public static final String INVOCATION_ID = "InvocationID"; + public static final String INSTANCE_UUID = "InstanceUUID"; + public static final String RESPONSE_CODE = "ResponseCode"; + public static final String SERVICE_NAME = "ServiceName"; + + private MDCVariables() { + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java new file mode 100644 index 0000000..0e4bd56 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/SimulatorController.java @@ -0,0 +1,219 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.JsonSyntaxException; +import org.json.JSONException; +import org.onap.pnfsimulator.event.EventData; +import org.onap.pnfsimulator.event.EventDataService; +import org.onap.pnfsimulator.rest.model.FullEvent; +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.simulatorconfig.SimulatorConfig; +import org.quartz.SchedulerException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.onap.pnfsimulator.logging.MDCVariables.INSTANCE_UUID; +import static org.onap.pnfsimulator.logging.MDCVariables.INVOCATION_ID; +import static org.onap.pnfsimulator.logging.MDCVariables.REQUEST_ID; +import static org.onap.pnfsimulator.logging.MDCVariables.RESPONSE_CODE; +import static org.onap.pnfsimulator.logging.MDCVariables.SERVICE_NAME; +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; +import static org.springframework.http.HttpStatus.OK; + +@RestController +@RequestMapping("/simulator") +public class SimulatorController { + + private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorController.class); + private static final Marker ENTRY = MarkerFactory.getMarker("ENTRY"); + private static final String INCORRECT_TEMPLATE_MESSAGE = "Cannot start simulator, template %s is not in valid format: %s"; + private static final String NOT_EXISTING_TEMPLATE = "Cannot start simulator - template %s not found."; + private final DateFormat responseDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss,SSS"); + private final SimulatorService simulatorService; + private EventDataService eventDataService; + + @Autowired + public SimulatorController(SimulatorService simulatorService, + EventDataService eventDataService) { + this.simulatorService = simulatorService; + this.eventDataService = eventDataService; + } + + @PostMapping("test") + @Deprecated + public ResponseEntity test(@Valid @RequestBody SimulatorRequest simulatorRequest) { + MDC.put("test", "test"); + LOGGER.info(ENTRY, simulatorRequest.toString()); + return buildResponse(OK, ImmutableMap.of(MESSAGE, "message1234")); + } + + @PostMapping(value = "start") + public ResponseEntity start(@RequestHeader HttpHeaders headers, + @Valid @RequestBody SimulatorRequest triggerEventRequest) { + logContextHeaders(headers, "/simulator/start"); + LOGGER.info(ENTRY, "Simulator started"); + + try { + return processRequest(triggerEventRequest); + + } catch (JSONException | JsonSyntaxException e) { + MDC.put(RESPONSE_CODE, BAD_REQUEST.toString()); + 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()))); + } 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")); + } + 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()))); + } 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())); + } finally { + MDC.clear(); + } + } + + @GetMapping("all-events") + @Deprecated + public ResponseEntity 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(); + } + + @GetMapping("config") + public ResponseEntity getConfig() { + SimulatorConfig configToGet = simulatorService.getConfiguration(); + return buildResponse(OK, ImmutableMap.of("simulatorConfig", configToGet)); + } + + @PutMapping("config") + public ResponseEntity 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 {}.", jobName); + boolean isCancelled = simulatorService.cancelEvent(jobName); + return createCancelEventResponse(isCancelled); + } + + @PostMapping("cancel") + public ResponseEntity 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) + 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")); + } + + private ResponseEntity 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 buildResponse(HttpStatus endStatus, Map<String, Object> parameters) { + ResponseBuilder builder = ResponseBuilder + .status(endStatus) + .put(TIMESTAMP, DateUtil.getTimestamp(responseDateFormat)); + parameters.forEach(builder::put); + return builder.build(); + } + + 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)); + MDC.put(INSTANCE_UUID, UUID.randomUUID().toString()); + MDC.put(SERVICE_NAME, serviceName); + } + + private ResponseEntity createCancelEventResponse(boolean isCancelled) { + if (isCancelled) { + return buildResponse(OK, ImmutableMap.of(MESSAGE, "Event(s) was cancelled")); + } else { + return buildResponse(NOT_FOUND, ImmutableMap.of(MESSAGE, "Simulator was not able to cancel event(s)")); + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/TemplateController.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/TemplateController.java new file mode 100644 index 0000000..444e23b --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/TemplateController.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.rest; + +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import javax.validation.Valid; + +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.rest.model.TemplateRequest; +import org.onap.pnfsimulator.rest.model.SearchExp; +import org.onap.pnfsimulator.template.Template; +import org.onap.pnfsimulator.template.search.IllegalJsonValueException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +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.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; + + +@RestController +@RequestMapping("/template") +public class TemplateController { + static final String TEMPLATE_NOT_FOUND_MSG = "A template with given name does not exist"; + static final String CANNOT_OVERRIDE_TEMPLATE_MSG = "Cannot overwrite existing template. Use override=true to override"; + private final Storage<Template> service; + private static final Logger LOG = LoggerFactory.getLogger(TemplateController.class); + + @Autowired + public TemplateController(Storage<Template> service) { + this.service = service; + } + + @GetMapping("list") + public ResponseEntity<?> list() { + return new ResponseEntity<>(service.getAll(), HttpStatus.OK); + } + + @GetMapping("get/{templateName}") + public ResponseEntity<?> get(@PathVariable String templateName) { + Optional<Template> template = service.get(templateName); + if (!template.isPresent()) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.TEXT_PLAIN); + return new ResponseEntity<>(TEMPLATE_NOT_FOUND_MSG, headers, HttpStatus.NOT_FOUND); + } + return new ResponseEntity<>(template, HttpStatus.OK); + } + + @PostMapping("upload") + public ResponseEntity<?> upload( + @RequestBody @Valid TemplateRequest templateRequest, + @RequestParam(required = false) boolean override) { + String msg = ""; + HttpStatus status = HttpStatus.CREATED; + Template template = new Template(templateRequest.getName(), templateRequest.getTemplate(), Instant.now().getNano()); + if (!service.tryPersistOrOverwrite(template, override)) { + status = HttpStatus.CONFLICT; + msg = CANNOT_OVERRIDE_TEMPLATE_MSG; + } + return new ResponseEntity<>(msg, status); + } + + @PostMapping("search") + public ResponseEntity<?> searchByCriteria(@RequestBody SearchExp queryJson) { + try { + List<String> templateNames = service.getIdsByContentCriteria(queryJson.getSearchExpr()); + return new ResponseEntity<>(templateNames, HttpStatus.OK); + } catch (IllegalJsonValueException ex) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, String.format("Try again with correct parameters. Cause: %s", ex.getMessage()), ex); + } + + } + + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/FullEvent.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/FullEvent.java new file mode 100644 index 0000000..77d9b3d --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/FullEvent.java @@ -0,0 +1,48 @@ +/* + * ============LICENSE_START======================================================= + * FULL-EVENT + * ================================================================================ + * Copyright (C) 2018 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.rest.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.gson.JsonObject; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.pnfsimulator.rest.util.JsonObjectDeserializer; +import org.springframework.lang.Nullable; + +import javax.validation.constraints.NotNull; + +@AllArgsConstructor +@NoArgsConstructor +@Getter +@ToString +@EqualsAndHashCode +public class FullEvent { + + @Nullable + private String vesServerUrl; + + @NotNull + @JsonDeserialize(using = JsonObjectDeserializer.class) + private JsonObject event; +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SearchExp.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SearchExp.java new file mode 100644 index 0000000..41d112f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SearchExp.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.rest.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.gson.JsonObject; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.pnfsimulator.rest.util.JsonObjectDeserializer; + +import javax.validation.constraints.NotNull; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class SearchExp { + + @NotNull + @JsonDeserialize(using = JsonObjectDeserializer.class) + private JsonObject searchExpr; +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorParams.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorParams.java new file mode 100644 index 0000000..787583e --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorParams.java @@ -0,0 +1,46 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.model; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotNull; +import org.springframework.lang.Nullable; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +@NoArgsConstructor +public class SimulatorParams { + + @NotNull + private String vesServerUrl; + + @Nullable + private Integer repeatInterval; + + @Nullable + private Integer repeatCount; + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorRequest.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorRequest.java new file mode 100644 index 0000000..2b06658 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/SimulatorRequest.java @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.model; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.google.gson.JsonObject; +import javax.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.pnfsimulator.rest.util.JsonObjectDeserializer; +import org.springframework.lang.Nullable; + +@Getter +@ToString +@EqualsAndHashCode +@AllArgsConstructor +@NoArgsConstructor +public class SimulatorRequest { + + @NotNull + private SimulatorParams simulatorParams; + + @NotNull + private String templateName; + + @Nullable + @JsonDeserialize(using = JsonObjectDeserializer.class) + private JsonObject patch; + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/TemplateRequest.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/TemplateRequest.java new file mode 100644 index 0000000..d5a77f0 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/model/TemplateRequest.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.rest.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import org.bson.Document; + +@Getter +@Setter +@ToString +public class TemplateRequest { + private String name; + private Document template; + + public TemplateRequest(String name, Document template) { + this.name = name; + this.template = template; + } + + public TemplateRequest() { + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/DateUtil.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/DateUtil.java new file mode 100644 index 0000000..9a5c9ca --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/DateUtil.java @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.util; + +import java.text.DateFormat; +import java.util.Date; + +public final class DateUtil { + + private DateUtil() { + } + + public static String getTimestamp(DateFormat dateFormat) { + + return dateFormat.format(new Date()); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/JsonObjectDeserializer.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/JsonObjectDeserializer.java new file mode 100644 index 0000000..f89c4a7 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/JsonObjectDeserializer.java @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.util; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import java.io.IOException; + +public class JsonObjectDeserializer extends JsonDeserializer<JsonObject> { + private Gson gson = new Gson(); + + @Override + public JsonObject deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + return gson.fromJson(node.toString(), JsonObject.class); + } +} 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 new file mode 100644 index 0000000..5fca25a --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/rest/util/ResponseBuilder.java @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.util; + +import java.util.LinkedHashMap; +import java.util.Map; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +public class ResponseBuilder { + + public static final String TIMESTAMP = "timestamp"; + public static final String MESSAGE = "message"; + public static final String SIMULATOR_STATUS = "simulatorStatus"; + public static final String REMAINING_TIME = "remainingTime"; + + private HttpStatus httpStatus; + private Map<String, Object> body = new LinkedHashMap<>(); + + private ResponseBuilder(HttpStatus httpStatus) { + this.httpStatus = httpStatus; + } + + public static ResponseBuilder status(HttpStatus httpStatus) { + + return new ResponseBuilder(httpStatus); + } + + public ResponseBuilder put(String key, Object value) { + + body.put(key, value); + return this; + } + + public ResponseEntity build() { + + if (body.isEmpty()) { + return ResponseEntity.status(httpStatus).build(); + } + + return ResponseEntity.status(httpStatus).body(body); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/DBTemplateReader.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/DBTemplateReader.java new file mode 100644 index 0000000..6c11254 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/DBTemplateReader.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.io.IOException; +import org.onap.pnfsimulator.template.Template; +import org.onap.pnfsimulator.template.TemplateService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class DBTemplateReader implements TemplateReader { + private final TemplateService service; + private final Gson gson; + + @Autowired + public DBTemplateReader(TemplateService service, Gson gson) { + this.service = service; + this.gson = gson; + } + + @Override + public JsonObject readTemplate(String templateName) throws IOException { + Template template = service.get(templateName).orElseThrow(() -> new IOException("Template does not exist")); + JsonElement jsonElement = gson.toJsonTree(template.getContent()); + return jsonElement.getAsJsonObject(); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/EventNotFoundException.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/EventNotFoundException.java new file mode 100644 index 0000000..4f43d8c --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/EventNotFoundException.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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 EventNotFoundException extends RuntimeException { + private static final String NOT_FOUND = "Not found an event with id: "; + public EventNotFoundException(String eventId) { + super(NOT_FOUND + eventId); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/FilesystemTemplateReader.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/FilesystemTemplateReader.java new file mode 100644 index 0000000..a405a2e --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/FilesystemTemplateReader.java @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +class FilesystemTemplateReader implements TemplateReader { + + private final Path templatesDir; + private final Gson gson; + + @Autowired + FilesystemTemplateReader(@Value("${templates.dir}") String templatesDir, Gson gson) { + this.templatesDir = Paths.get(templatesDir); + this.gson = gson; + } + + public JsonObject readTemplate(String templateFileName) throws IOException { + Path absTemplateFilePath = templatesDir.resolve(templateFileName); + try (Stream<String> lines = Files.lines(absTemplateFilePath)) { + String content = lines.collect(Collectors.joining("\n")); + return gson.fromJson(content, JsonObject.class); + } + } +} + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProvider.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProvider.java new file mode 100644 index 0000000..ea87ae6 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProvider.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +@FunctionalInterface +public interface IncrementProvider { + int getAndIncrement(String id); +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProviderImpl.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProviderImpl.java new file mode 100644 index 0000000..16c0a0e --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/IncrementProviderImpl.java @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import org.onap.pnfsimulator.event.EventData; +import org.onap.pnfsimulator.event.EventDataRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class IncrementProviderImpl implements IncrementProvider { + private final EventDataRepository repository; + + @Autowired + public IncrementProviderImpl(EventDataRepository repository) { + this.repository = repository; + } + + @Override + public int getAndIncrement(String id) { + EventData eventData = repository.findById(id) + .orElseThrow(() -> new EventNotFoundException(id)); + int value = eventData.getIncrementValue() + 1; + eventData.setIncrementValue(value); + repository.save(eventData); + return value; + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/JsonTokenProcessor.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/JsonTokenProcessor.java new file mode 100644 index 0000000..da0026a --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/JsonTokenProcessor.java @@ -0,0 +1,134 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.stream.JsonReader; +import com.google.gson.stream.JsonToken; +import com.google.gson.stream.JsonWriter; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.stream.Collectors; + +public enum JsonTokenProcessor { + STRING(JsonToken.STRING) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + String originalString = reader.nextString(); + if (keywordsExtractor.isPrimitive(originalString)) { + writer.value(keywordsExtractor.substitutePrimitiveKeyword(originalString)); + } else { + String possibleSubstitution = Arrays.stream(originalString.split(" ")) + .map(singleWord -> keywordsExtractor.substituteStringKeyword(singleWord, incrementValue)).collect( + Collectors.joining(" ")); + writer.value(originalString.equals(possibleSubstitution) ? originalString : possibleSubstitution); + } + } + }, + BEGIN_ARRAY(JsonToken.BEGIN_ARRAY) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + reader.beginArray(); + writer.beginArray(); + } + }, + END_ARRAY(JsonToken.END_ARRAY) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + reader.endArray(); + writer.endArray(); + } + }, + BEGIN_OBJECT(JsonToken.BEGIN_OBJECT) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + reader.beginObject(); + writer.beginObject(); + } + }, + END_OBJECT(JsonToken.END_OBJECT) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + reader.endObject(); + writer.endObject(); + } + }, + NAME(JsonToken.NAME) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + writer.name(reader.nextName()); + } + }, + NUMBER(JsonToken.NUMBER) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + writer.value(new BigDecimal(reader.nextString())); + } + }, + BOOLEAN(JsonToken.BOOLEAN) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + writer.value(reader.nextBoolean()); + } + }, + NULL(JsonToken.NULL) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + reader.nextNull(); + writer.nullValue(); + } + }, + END_DOCUMENT(JsonToken.END_DOCUMENT) { + @Override + void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) + throws IOException { + // do nothing + } + }; + + private JsonToken jsonToken; + + JsonTokenProcessor(JsonToken jsonToken) { + this.jsonToken = jsonToken; + } + + boolean isProcessorFor(JsonToken jsonToken) { + return this.jsonToken == jsonToken; + } + + abstract void process(JsonReader reader, JsonWriter writer, int incrementValue, KeywordsExtractor keywordsExtractor) throws IOException; + + private static final String INVALID_JSON_BODY_UNSUPPORTED_JSON_TOKEN = "Invalid json body. Unsupported JsonToken."; + + static JsonTokenProcessor getProcessorFor(JsonToken jsonToken) throws IOException { + return Arrays.stream(JsonTokenProcessor.values()).filter(processor -> processor.isProcessorFor(jsonToken)).findFirst() + .orElseThrow(() -> new IOException(INVALID_JSON_BODY_UNSUPPORTED_JSON_TOKEN)); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsExtractor.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsExtractor.java new file mode 100644 index 0000000..23c383f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsExtractor.java @@ -0,0 +1,118 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static io.vavr.API.$; +import static io.vavr.API.Case; +import static io.vavr.API.Match; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getEpochSecond; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getRandomLimitedInteger; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getRandomInteger; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getRandomLimitedString; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getRandomString; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getRandomPrimitiveInteger; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.getTimestampPrimitive; +import static org.onap.pnfsimulator.simulator.keywords.NonParameterKeywordPatterns.$nonParameterKeyword; +import static org.onap.pnfsimulator.simulator.keywords.SingleParameterKeywordPatterns.$singleParameterKeyword; +import static org.onap.pnfsimulator.simulator.keywords.TwoParameterKeywordPatterns.$twoParameterKeyword; +import io.vavr.API.Match.Pattern1; +import org.onap.pnfsimulator.simulator.keywords.Keyword; +import org.onap.pnfsimulator.simulator.keywords.NonParameterKeyword; +import org.onap.pnfsimulator.simulator.keywords.SingleParameterKeyword; +import org.onap.pnfsimulator.simulator.keywords.TwoParameterKeyword; +import org.springframework.stereotype.Component; + +@Component +public class KeywordsExtractor { + + String substituteStringKeyword(String text, int increment) { + return Match(text).of( + Case(isRandomStringParamKeyword(), + spk -> spk.substituteKeyword(getRandomString().apply(spk.getAdditionalParameter()))), + Case(isRandomStringNonParamKeyword(), + npk -> npk.substituteKeyword(getRandomLimitedString().apply())), + Case(isRandomIntegerParamKeyword(), + tpk -> tpk.substituteKeyword(getRandomInteger().apply(tpk.getAdditionalParameter1(), tpk.getAdditionalParameter2()))), + Case(isRandomIntegerNonParamKeyword(), + npk -> npk.substituteKeyword(getRandomLimitedInteger().apply())), + Case(isIncrementKeyword(), + ik -> ik.substituteKeyword(String.valueOf(increment))), + Case(isTimestampNonParamKeyword(), + npk -> npk.substituteKeyword(getEpochSecond().apply())), + Case( + $(), + () -> text + )); + } + + Long substitutePrimitiveKeyword(String text) { + return Match(text).of( + Case(isRandomPrimitiveIntegerParamKeyword(), + tpk -> + getRandomPrimitiveInteger().apply(tpk.getAdditionalParameter1(), tpk.getAdditionalParameter2())), + Case(isTimestampPrimitiveNonParamKeyword(), + tpk -> + getTimestampPrimitive().apply()), + Case( + $(), + () -> 0L + )); + } + + boolean isPrimitive(String text) { + return Match(text).of( + Case(isRandomPrimitiveIntegerParamKeyword(), () -> true), + Case(isTimestampPrimitiveNonParamKeyword(), () -> true), + Case($(), () -> false)); + } + + private Pattern1<String, SingleParameterKeyword> isRandomStringParamKeyword() { + return $singleParameterKeyword($(spk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(spk, "RandomString"))); + } + + private Pattern1<String, NonParameterKeyword> isRandomStringNonParamKeyword() { + return $nonParameterKeyword($(npk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(npk, "RandomString"))); + } + + private Pattern1<String, NonParameterKeyword> isIncrementKeyword() { + return $nonParameterKeyword($(npk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(npk, "Increment"))); + } + + private Pattern1<String, TwoParameterKeyword> isRandomIntegerParamKeyword() { + return $twoParameterKeyword($(tpk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(tpk, "RandomInteger"))); + } + + private Pattern1<String, TwoParameterKeyword> isRandomPrimitiveIntegerParamKeyword() { + return $twoParameterKeyword($(tpk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(tpk, "RandomPrimitiveInteger"))); + } + + private Pattern1<String, NonParameterKeyword> isTimestampPrimitiveNonParamKeyword() { + return $nonParameterKeyword($(npk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(npk, "TimestampPrimitive"))); + } + + private Pattern1<String, NonParameterKeyword> isRandomIntegerNonParamKeyword() { + return $nonParameterKeyword($(npk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(npk, "RandomInteger"))); + } + + private Pattern1<String, NonParameterKeyword> isTimestampNonParamKeyword() { + return $nonParameterKeyword($(npk -> Keyword.IS_MATCHING_KEYWORD_NAME.apply(npk, "Timestamp"))); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java new file mode 100644 index 0000000..51e0c1f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsHandler.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.Gson; +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 +public class KeywordsHandler { + + private KeywordsExtractor keywordsExtractor; + private IncrementProvider incrementProvider; + + public KeywordsHandler(KeywordsExtractor keywordsExtractor, IncrementProvider incrementProvider) { + this.keywordsExtractor = keywordsExtractor; + this.incrementProvider = incrementProvider; + } + + 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); + ) { + modify(reader, jsonWriter, counter); + return new Gson().fromJson(stringWriter.getBuffer().toString(), JsonElement.class); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void modify(JsonReader reader, JsonWriter writer, int incrementValue) throws IOException { + JsonTokenProcessor jsonTokenProcessor; + do { + JsonToken token = reader.peek(); + jsonTokenProcessor = JsonTokenProcessor.getProcessorFor(token); + jsonTokenProcessor.process(reader, writer, incrementValue, keywordsExtractor); + } while (isJsonProcessingFinished(jsonTokenProcessor)); + } + + private boolean isJsonProcessingFinished(JsonTokenProcessor jsonTokenProcessor) { + return !jsonTokenProcessor.isProcessorFor(JsonToken.END_DOCUMENT); + } + +} + + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsValueProvider.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsValueProvider.java new file mode 100644 index 0000000..3bcfa5b --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/KeywordsValueProvider.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import io.vavr.Function0; +import io.vavr.Function1; +import io.vavr.Function2; + +import java.time.Instant; +import java.util.Random; + +import org.apache.commons.lang3.RandomStringUtils; + +class KeywordsValueProvider { + + private KeywordsValueProvider() { + } + + static final int DEFAULT_STRING_LENGTH = 20; + public static final int RANDOM_INTEGER_MAX_LIMITATION = 9; + public static final int RANDOM_INTEGER_MIN_LIMITATION = 0; + + private static Function2<Integer, Integer, Integer> bigger = (left, right) -> left >= right ? left : right; + private static Function2<Integer, Integer, Integer> smaller = (left, right) -> left < right ? left : right; + private static Function2<Integer, Integer, Integer> randomPrimitiveIntegerFromSortedRange = (min, max) -> new Random().nextInt(max - min + 1) + min; + private static Function2<Integer, Integer, String> randomIntegerFromSortedRange = (min, max) -> Integer.toString(new Random().nextInt(max - min + 1) + min); + + private static Function1<Integer, String> randomString = RandomStringUtils::randomAscii; + private static Function2<Integer, Integer, String> randomInteger = (left, right) -> randomIntegerFromSortedRange.apply(smaller.apply(left, right), bigger.apply(left, right)); + private static Function0<String> randomLimitedInteger = () -> randomInteger.apply(RANDOM_INTEGER_MIN_LIMITATION, RANDOM_INTEGER_MAX_LIMITATION); + private static Function0<String> randomLimitedString = () -> RandomStringUtils.randomAscii(DEFAULT_STRING_LENGTH); + private static Function0<String> epochSecond = () -> Long.toString(Instant.now().getEpochSecond()); + private static Function2<Integer, Integer, Long> randomPrimitiveInteger = (left, right) -> randomPrimitiveIntegerFromSortedRange.apply(smaller.apply(left, right), bigger.apply(left, right)).longValue(); + private static Function0<Long> timestampPrimitive = () -> Instant.now().getEpochSecond(); + + public static Function1<Integer, String> getRandomString() { + return randomString; + } + + public static Function2<Integer, Integer, String> getRandomInteger() { + return randomInteger; + } + + public static Function0<String> getRandomLimitedInteger() { + return randomLimitedInteger; + } + + public static Function0<String> getRandomLimitedString() { + return randomLimitedString; + } + + public static Function0<String> getEpochSecond() { + return epochSecond; + } + + public static Function2<Integer, Integer, Long> getRandomPrimitiveInteger() { + return randomPrimitiveInteger; + } + + public static Function0<Long> getTimestampPrimitive() { + return timestampPrimitive; + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java new file mode 100644 index 0000000..155c0ff --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/SimulatorService.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.common.base.Strings; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.Optional; +import org.onap.pnfsimulator.event.EventData; +import org.onap.pnfsimulator.event.EventDataService; +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.HttpClientAdapterImpl; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.onap.pnfsimulator.simulator.scheduler.EventScheduler; +import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig; +import org.onap.pnfsimulator.simulatorconfig.SimulatorConfigService; +import org.quartz.SchedulerException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class SimulatorService { + + private final TemplatePatcher templatePatcher; + private final TemplateReader templateReader; + private final EventDataService eventDataService; + private final EventScheduler eventScheduler; + private final SSLAuthenticationHelper sslAuthenticationHelper; + private SimulatorConfigService simulatorConfigService; + private static final JsonObject EMPTY_JSON_OBJECT = new JsonObject(); + + @Autowired + public SimulatorService(TemplatePatcher templatePatcher, TemplateReader templateReader, + EventScheduler eventScheduler, EventDataService eventDataService, + SimulatorConfigService simulatorConfigService, SSLAuthenticationHelper sslAuthenticationHelper) { + this.templatePatcher = templatePatcher; + this.templateReader = templateReader; + this.eventDataService = eventDataService; + this.eventScheduler = eventScheduler; + this.simulatorConfigService = simulatorConfigService; + this.sslAuthenticationHelper = sslAuthenticationHelper; + } + + public String triggerEvent(SimulatorRequest simulatorRequest) throws IOException, SchedulerException, GeneralSecurityException { + String templateName = simulatorRequest.getTemplateName(); + SimulatorParams simulatorParams = simulatorRequest.getSimulatorParams(); + JsonObject template = templateReader.readTemplate(templateName); + JsonObject input = Optional.ofNullable(simulatorRequest.getPatch()).orElse(new JsonObject()); + JsonObject patchedJson = templatePatcher + .mergeTemplateWithPatch(template, input); + JsonObject keywords = new JsonObject(); + + EventData eventData = eventDataService.persistEventData(template, patchedJson, input, keywords); + + String targetVesUrl = getDefaultUrlIfNotProvided(simulatorParams.getVesServerUrl()); + return eventScheduler + .scheduleEvent(targetVesUrl, Optional.ofNullable(simulatorParams.getRepeatInterval()).orElse(1), + Optional.ofNullable(simulatorParams.getRepeatCount()).orElse(1), simulatorRequest.getTemplateName(), + eventData.getId(), + patchedJson); + } + + public void 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()); + } + + public SimulatorConfig getConfiguration() { + return simulatorConfigService.getConfiguration(); + } + + public SimulatorConfig updateConfiguration(SimulatorConfig newConfig) { + return simulatorConfigService.updateConfiguration(newConfig); + } + + public boolean cancelAllEvents() throws SchedulerException { + return eventScheduler.cancelAllEvents(); + } + + public boolean cancelEvent(String jobName) throws SchedulerException { + return eventScheduler.cancelEvent(jobName); + } + + HttpClientAdapter createHttpClientAdapter(String vesServerUrl) throws IOException, GeneralSecurityException { + String targetVesUrl = getDefaultUrlIfNotProvided(vesServerUrl); + return new HttpClientAdapterImpl(targetVesUrl, sslAuthenticationHelper); + } + + private String getDefaultUrlIfNotProvided(String vesUrlSimulatorParam) { + return Strings.isNullOrEmpty(vesUrlSimulatorParam) + ? simulatorConfigService.getConfiguration().getVesServerUrl().toString() : vesUrlSimulatorParam; + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplatePatcher.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplatePatcher.java new file mode 100644 index 0000000..1114d3c --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplatePatcher.java @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Component +class TemplatePatcher { + + JsonObject mergeTemplateWithPatch(JsonObject templateJson, JsonObject patchJson) { + JsonObject template = templateJson.deepCopy(); + patchTemplateNode(template, patchJson); + return template; + } + + private void patchTemplateNode(JsonObject templateJson, JsonObject patchJson) { + for (Map.Entry<String, JsonElement> stringJsonElementEntry : patchJson.entrySet()) { + String patchKey = stringJsonElementEntry.getKey(); + JsonElement patchValue = stringJsonElementEntry.getValue(); + JsonElement templateElement = templateJson.get(patchKey); + + if (!patchValue.isJsonObject() || templateElement == null || !templateElement.isJsonObject()) { + templateJson.remove(patchKey); + templateJson.add(patchKey, patchValue); + } else { + patchTemplateNode(templateElement.getAsJsonObject(), patchValue.getAsJsonObject()); + } + + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplateReader.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplateReader.java new file mode 100644 index 0000000..bf06381 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/TemplateReader.java @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.JsonObject; +import java.io.IOException; + +public interface TemplateReader { + JsonObject readTemplate(String templateName) throws IOException; +} 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 new file mode 100644 index 0000000..e7d113d --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapter.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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 interface HttpClientAdapter { + + void 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 new file mode 100644 index 0000000..6ea1157 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImpl.java @@ -0,0 +1,104 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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 static org.onap.pnfsimulator.logging.MDCVariables.REQUEST_ID; +import static org.onap.pnfsimulator.logging.MDCVariables.X_INVOCATION_ID; +import static org.onap.pnfsimulator.logging.MDCVariables.X_ONAP_REQUEST_ID; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.util.UUID; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SslSupportLevel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +public class HttpClientAdapterImpl implements HttpClientAdapter { + + private static final int CONNECTION_TIMEOUT = 1000; + private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientAdapterImpl.class); + private static final String CONTENT_TYPE = "Content-Type"; + private static final String APPLICATION_JSON = "application/json"; + private static final RequestConfig CONFIG = RequestConfig.custom() + .setConnectTimeout(CONNECTION_TIMEOUT) + .setConnectionRequestTimeout(CONNECTION_TIMEOUT) + .setSocketTimeout(CONNECTION_TIMEOUT) + .build(); + private static final Marker INVOKE = MarkerFactory.getMarker("INVOKE"); + private SslSupportLevel sslSupportLevel; + private HttpClient client; + private final String targetUrl; + + public HttpClientAdapterImpl(String targetUrl, SSLAuthenticationHelper sslAuthenticationHelper) + throws IOException, GeneralSecurityException { + this.sslSupportLevel = sslAuthenticationHelper.isClientCertificateEnabled() ? + SslSupportLevel.CLIENT_CERT_AUTH : SslSupportLevel.getSupportLevelBasedOnProtocol(targetUrl); + this.client = sslSupportLevel.getClient(CONFIG, sslAuthenticationHelper); + this.targetUrl = targetUrl; + } + + HttpClientAdapterImpl(HttpClient client, String targetUrl) { + this.client = client; + this.targetUrl = targetUrl; + } + + @Override + public void send(String content) { + try { + HttpPost request = createRequest(content); + HttpResponse response = client.execute(request); + + //response has to be fully consumed otherwise apache won't release connection + EntityUtils.consumeQuietly(response.getEntity()); + LOGGER.info(INVOKE, "Message sent, ves response code: {}", response.getStatusLine()); + } catch (IOException e) { + LOGGER.warn("Error sending message to ves: " + e.getMessage(), e.getCause()); + } + } + + public SslSupportLevel getSslSupportLevel(){ + return sslSupportLevel; + } + + private HttpPost createRequest(String content) throws UnsupportedEncodingException { + HttpPost request = new HttpPost(this.targetUrl); + StringEntity stringEntity = new StringEntity(content); + request.addHeader(CONTENT_TYPE, APPLICATION_JSON); + request.addHeader(X_ONAP_REQUEST_ID, MDC.get(REQUEST_ID)); + request.addHeader(X_INVOCATION_ID, UUID.randomUUID().toString()); + request.setEntity(stringEntity); + return request; + } + + +} 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 new file mode 100644 index 0000000..eda17ef --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SSLAuthenticationHelper.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 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.utils.ssl; + +import java.io.Serializable; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "ssl") +@RefreshScope +@Primary +public class SSLAuthenticationHelper implements Serializable { + + private boolean clientCertificateEnabled; + private String clientCertificateDir; + 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/simulator/client/utils/ssl/SslSupportLevel.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslSupportLevel.java new file mode 100644 index 0000000..264a7d1 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslSupportLevel.java @@ -0,0 +1,120 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.utils.ssl; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.TrustAllStrategy; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.conn.ssl.TrustStrategy; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.SSLContexts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.GeneralSecurityException; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.util.Optional; + +public enum SslSupportLevel { + + NONE { + public HttpClient getClient(RequestConfig requestConfig, SSLAuthenticationHelper sslAuthenticationHelper) { + LOGGER.info("<!-----IN SslSupportLevel.NONE, Creating BasicHttpClient for http protocol----!>"); + return HttpClientBuilder + .create() + .setDefaultRequestConfig(requestConfig) + .build(); + } + }, + ALWAYS_TRUST { + public HttpClient getClient(RequestConfig requestConfig, SSLAuthenticationHelper sslAuthenticationHelper) + throws GeneralSecurityException, IOException { + LoggerFactory.getLogger(SslSupportLevel.class).info("<!-----IN SslSupportLevel.ALWAYS_TRUST, Creating client with SSL support for https protocol----!>"); + HttpClient client; + try { + SSLContext alwaysTrustSslContext = SSLContextBuilder.create().loadTrustMaterial(TRUST_STRATEGY_ALWAYS).build(); + client = HttpClients.custom() + .setSSLContext(alwaysTrustSslContext) + .setSSLHostnameVerifier(new NoopHostnameVerifier()) + .setDefaultRequestConfig(requestConfig) + .build(); + + } catch (GeneralSecurityException e) { + LOGGER.error("Could not initialize client due to SSL exception: {}. Default client without SSL support will be used instead.\nCause: {}", e.getMessage(), e.getCause()); + client = NONE.getClient(requestConfig, sslAuthenticationHelper); + } + return client; + } + }, + CLIENT_CERT_AUTH { + @Override + public HttpClient getClient(RequestConfig requestConfig, SSLAuthenticationHelper sslAuthenticationHelper) + throws GeneralSecurityException, IOException { + + SSLContext sslContext = SSLContexts.custom() + .loadKeyMaterial(readCertificate(sslAuthenticationHelper.getClientCertificateDir(), sslAuthenticationHelper.getClientCertificatePassword(), "PKCS12"), getPasswordAsCharArray(sslAuthenticationHelper.getClientCertificatePassword())) + .loadTrustMaterial(readCertificate(sslAuthenticationHelper.getTrustStoreDir(), sslAuthenticationHelper.getTrustStorePassword(), "JKS"), new TrustSelfSignedStrategy()) + .build(); + + return HttpClients.custom() + .setSSLContext(sslContext) + .setSSLHostnameVerifier(new NoopHostnameVerifier()) + .setDefaultRequestConfig(requestConfig) + .build(); + } + + private KeyStore readCertificate(String certificate, String password, String type) throws GeneralSecurityException, IOException { + try (InputStream keyStoreStream = new FileInputStream(certificate)) { + KeyStore keyStore = KeyStore.getInstance(type); + keyStore.load(keyStoreStream, getPasswordAsCharArray(password)); + return keyStore; + } + } + + private char[] getPasswordAsCharArray(String clientCertificatePassword) { + return Optional.ofNullable(clientCertificatePassword).map(String::toCharArray).orElse(null); + } + }; + + private static final Logger LOGGER = LoggerFactory.getLogger(SslSupportLevel.class); + private static final TrustStrategy TRUST_STRATEGY_ALWAYS = new TrustAllStrategy(); + + public static SslSupportLevel getSupportLevelBasedOnProtocol(String url) throws MalformedURLException { + return "https".equals(new URL(url).getProtocol()) ? SslSupportLevel.ALWAYS_TRUST : SslSupportLevel.NONE; + } + + public abstract HttpClient getClient(RequestConfig config, SSLAuthenticationHelper sslAuthenticationHelper) + throws GeneralSecurityException, IOException; + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/Keyword.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/Keyword.java new file mode 100644 index 0000000..edafe8f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/Keyword.java @@ -0,0 +1,74 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.Function1; +import io.vavr.Function2; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.stream.Collectors; +import lombok.Getter; + +@Getter +public class Keyword { + + protected static final String LETTERS_REGEX = "([a-zA-Z]+)"; + protected static final String NONLETTERS_REGEX = "([^a-zA-Z]+)"; + + protected static final Function1<String, String> OPTIONAL = + (regex) -> regex + "?"; + + private final String name; + private final List<String> meaningfulParts; + + public static final Function2<Keyword, String, Boolean> IS_MATCHING_KEYWORD_NAME = (keyword, key) -> + keyword != null && keyword.getName() != null && keyword.getName().equals(key); + + /** + * Returns list of independent parts inside the keyword. Current implementation assumes that customer can join keywords with integer values, so + * keyword is decomposed to parts then some parts of the keyword is skipped because of replacement process. + * + * @param matcher - Matcher to check find independent groups inside the keyword + * @param skipGroups Informs this method about which groups should be consider as part of the replacement process + * @return list of independent parts inside the keywords + */ + static List<String> extractPartsFrom(Matcher matcher, List skipGroups) { + List<String> parts = new ArrayList<String>(); + for (int i = 1; i <= matcher.groupCount(); i++) { + if (matcher.group(i) != null && !skipGroups.contains(i)) { + parts.add(matcher.group(i)); + } + } + return parts; + } + + Keyword(String name, List<String> meaningfulParts) { + this.name = name; + this.meaningfulParts = meaningfulParts; + } + + public String substituteKeyword(String substitution) { + return meaningfulParts.stream() + .map(part -> part.equals(name) ? substitution : part) + .collect(Collectors.joining()); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/NonParameterKeyword.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/NonParameterKeyword.java new file mode 100644 index 0000000..5e44550 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/NonParameterKeyword.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.Tuple; +import io.vavr.Tuple1; +import io.vavr.match.annotation.Patterns; +import io.vavr.match.annotation.Unapply; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import lombok.Getter; +import lombok.Setter; +import lombok.val; + +@Patterns +@Getter +@Setter +public class NonParameterKeyword extends Keyword { + + public static final int KEYWORD_NAME_GROUP = 2; + + private static final String KEYWORD_REGEX = new StringBuilder() + .append(OPTIONAL.apply(NONLETTERS_REGEX)) + .append("#") + .append(LETTERS_REGEX) + .append("(?!\\()") + .append(OPTIONAL.apply(NONLETTERS_REGEX)) + .toString(); + + private NonParameterKeyword(String name, List<String> meaningfulParts) { + super(name, meaningfulParts); + } + + @Unapply + static Tuple1<NonParameterKeyword> nonParameterKeyword(String keyword) { + val matcher = Pattern.compile(KEYWORD_REGEX).matcher(keyword); + NonParameterKeyword npk = null; + if (matcher.find()) { + npk = new NonParameterKeyword( + matcher.group(KEYWORD_NAME_GROUP), + extractPartsFrom(matcher, Collections.emptyList()) + ); + } + return Tuple.of(npk); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/SingleParameterKeyword.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/SingleParameterKeyword.java new file mode 100644 index 0000000..b1c38c8 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/SingleParameterKeyword.java @@ -0,0 +1,73 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.Tuple; +import io.vavr.Tuple1; +import io.vavr.match.annotation.Patterns; +import io.vavr.match.annotation.Unapply; +import java.util.Collections; +import java.util.List; +import java.util.regex.Pattern; +import lombok.Getter; +import lombok.Setter; +import lombok.val; + +@Patterns +@Getter +@Setter +public class SingleParameterKeyword extends Keyword { + + public static final int KEYWORD_NAME_GROUP = 2; + public static final int ADDITIONAL_PARAMETER_GROUP = 3; + + private static final String KEYWORD_REGEX = new StringBuilder() + .append(OPTIONAL.apply(NONLETTERS_REGEX)) + .append("#") + .append(LETTERS_REGEX) + .append("\\((\\d+)\\)") + .append(OPTIONAL.apply(NONLETTERS_REGEX)) + .toString(); + public static final int SKIPPED_GROUP_NUMBER = 3; + + private Integer additionalParameter; + + private SingleParameterKeyword(String name, List<String> meaningfulParts, + Integer additionalParameter) { + super(name, meaningfulParts); + this.additionalParameter = additionalParameter; + } + + @Unapply + static Tuple1<SingleParameterKeyword> singleParameterKeyword(String keyword) { + val matcher = Pattern.compile(KEYWORD_REGEX).matcher(keyword); + SingleParameterKeyword spk = null; + if (matcher.find()) { + spk = new SingleParameterKeyword( + matcher.group(KEYWORD_NAME_GROUP), + extractPartsFrom(matcher, Collections.singletonList(SKIPPED_GROUP_NUMBER)), + Integer.parseInt(matcher.group(ADDITIONAL_PARAMETER_GROUP)) + ); + } + return Tuple.of(spk); + } +} + + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeyword.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeyword.java new file mode 100644 index 0000000..6fecfa6 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/keywords/TwoParameterKeyword.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.Tuple; +import io.vavr.Tuple1; +import io.vavr.match.annotation.Patterns; +import io.vavr.match.annotation.Unapply; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Pattern; +import lombok.Getter; +import lombok.Setter; +import lombok.val; + +@Patterns +@Getter +@Setter +public class TwoParameterKeyword extends Keyword { + + public static final int ADDITIONAL_PARAMETER_1_GROUP = 3; + public static final int ADDITIONAL_PARAMETER_2_GROUP = 4; + public static final int KEYWORD_NAME_GROUP = 2; + protected static final List<Integer> ADDITIONAL_PARAMETERS_GROUPS = Arrays.asList(ADDITIONAL_PARAMETER_1_GROUP, ADDITIONAL_PARAMETER_2_GROUP); + + private static final String NON_LIMITED_NUMBER_REGEX = "\\((\\d+)"; + private static final String COLON_REGEX = "\\s?,\\s?"; + private static final String OPTIONAL_NUMBER_PARAM_REGEX = "(\\d+)\\)"; + + private static final String KEYWORD_REGEX = OPTIONAL.apply(NONLETTERS_REGEX) + + "#" + + LETTERS_REGEX + + NON_LIMITED_NUMBER_REGEX + + COLON_REGEX + + OPTIONAL_NUMBER_PARAM_REGEX + + OPTIONAL.apply(NONLETTERS_REGEX); + + private Integer additionalParameter1; + private Integer additionalParameter2; + + private TwoParameterKeyword(String name, List<String> meaningfulParts, Integer additionalParameter1, + Integer additionalParameter2) { + super(name, meaningfulParts); + this.additionalParameter1 = additionalParameter1; + this.additionalParameter2 = additionalParameter2; + } + + @Unapply + static Tuple1<TwoParameterKeyword> twoParameterKeyword(String keyword) { + val matcher = Pattern.compile(KEYWORD_REGEX).matcher(keyword); + TwoParameterKeyword tpk = null; + if (matcher.find()) { + tpk = new TwoParameterKeyword( + matcher.group(KEYWORD_NAME_GROUP), + extractPartsFrom(matcher, ADDITIONAL_PARAMETERS_GROUPS), + Integer.parseInt(matcher.group(ADDITIONAL_PARAMETER_1_GROUP)), + Integer.parseInt(matcher.group(ADDITIONAL_PARAMETER_2_GROUP)) + ); + } + return Tuple.of(tpk); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventJob.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventJob.java new file mode 100644 index 0000000..c4b40fc --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventJob.java @@ -0,0 +1,93 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.scheduler; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.onap.pnfsimulator.simulator.KeywordsHandler; +import org.onap.pnfsimulator.simulator.client.HttpClientAdapter; +import org.onap.pnfsimulator.simulator.client.HttpClientAdapterImpl; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.quartz.Job; +import org.quartz.JobDataMap; +import org.quartz.JobExecutionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.Optional; + +public class EventJob implements Job { + + private static final Logger LOGGER = LoggerFactory.getLogger(EventJob.class); + + static final String TEMPLATE_NAME = "TEMPLATE_NAME"; + static final String VES_URL = "VES_URL"; + static final String BODY = "BODY"; + static final String CLIENT_ADAPTER = "CLIENT_ADAPTER"; + static final String KEYWORDS_HANDLER = "KEYWORDS_HANDLER"; + static final String EVENT_ID = "EVENT_ID"; + + @Override + public void execute(JobExecutionContext jobExecutionContext) { + JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap(); + String templateName = jobDataMap.getString(TEMPLATE_NAME); + String vesUrl = jobDataMap.getString(VES_URL); + JsonObject body = (JsonObject) jobDataMap.get(BODY); + String id = jobDataMap.getString(EVENT_ID); + Optional<HttpClientAdapter> httpClientAdapter = getHttpClientAdapter(jobDataMap, vesUrl); + + if (httpClientAdapter.isPresent()) { + KeywordsHandler keywordsHandler = (KeywordsHandler) jobDataMap.get(KEYWORDS_HANDLER); + JsonElement processedBody = keywordsHandler.substituteKeywords(body, id); + String processedBodyString = processedBody.toString(); + String jobKey = jobExecutionContext.getJobDetail().getKey().toString(); + + logEventDetails(templateName, vesUrl, body.toString(), jobKey); + httpClientAdapter.get().send(processedBodyString); + } else { + LOGGER.error("Could not send event as client is not available"); + } + } + private Optional<HttpClientAdapter> getHttpClientAdapter(JobDataMap jobDataMap, String vesUrl) { + HttpClientAdapter adapter = null; + try { + adapter = (HttpClientAdapter) (jobDataMap.containsKey(CLIENT_ADAPTER) ? jobDataMap.get(CLIENT_ADAPTER) : + new HttpClientAdapterImpl(vesUrl, new SSLAuthenticationHelper())); + } catch (MalformedURLException e) { + LOGGER.error("Invalid format of vesServerUr: {}", vesUrl); + } catch (IOException | GeneralSecurityException e){ + LOGGER.error("Invalid configuration of client certificate"); + } + return Optional.ofNullable(adapter); + } + + private void logEventDetails(String templateName, String vesUrl, String body, String jobKey) { + LOGGER.info(String.format("Job %s:Sending event to %s from template %s", + jobKey, vesUrl, templateName)); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug(String.format("Job %s: Request body %s", jobKey, body)); + } + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventScheduler.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventScheduler.java new file mode 100644 index 0000000..08e24f8 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/EventScheduler.java @@ -0,0 +1,121 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.scheduler; + + +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.BODY; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.CLIENT_ADAPTER; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.EVENT_ID; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.KEYWORDS_HANDLER; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.TEMPLATE_NAME; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.VES_URL; +import static org.quartz.SimpleScheduleBuilder.simpleSchedule; + +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import org.onap.pnfsimulator.simulator.KeywordsHandler; +import org.onap.pnfsimulator.simulator.client.HttpClientAdapterImpl; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.quartz.JobBuilder; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SimpleTrigger; +import org.quartz.TriggerBuilder; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class EventScheduler { + + + private final Scheduler scheduler; + private final KeywordsHandler keywordsHandler; + private final SSLAuthenticationHelper SSLAuthenticationHelper; + + @Autowired + public EventScheduler(Scheduler scheduler, KeywordsHandler keywordsHandler, SSLAuthenticationHelper SSLAuthenticationHelper) { + this.scheduler = scheduler; + this.keywordsHandler = keywordsHandler; + this.SSLAuthenticationHelper = SSLAuthenticationHelper; + } + + public String scheduleEvent(String vesUrl, Integer repeatInterval, Integer repeatCount, + String templateName, String eventId, JsonObject body) + throws SchedulerException, IOException, GeneralSecurityException { + + JobDetail jobDetail = createJobDetail(vesUrl, templateName, eventId, body); + SimpleTrigger trigger = createTrigger(repeatInterval, repeatCount); + + scheduler.scheduleJob(jobDetail, trigger); + return jobDetail.getKey().getName(); + } + + public boolean cancelAllEvents() throws SchedulerException { + List<JobKey> jobKeys = getActiveJobsKeys(); + return scheduler.deleteJobs(jobKeys); + } + + public boolean cancelEvent(String jobName) throws SchedulerException { + Optional<JobKey> activeJobKey = getActiveJobsKeys().stream().filter(e -> e.getName().equals(jobName)).findFirst(); + return activeJobKey.isPresent() && scheduler.deleteJob(activeJobKey.get()); + } + + private SimpleTrigger createTrigger(int interval, int repeatCount) { + return TriggerBuilder.newTrigger() + .withSchedule(simpleSchedule() + .withIntervalInSeconds(interval) + .withRepeatCount(repeatCount - 1)) + .build(); + } + + private JobDetail createJobDetail(String vesUrl, String templateName, String eventId, JsonObject body) throws IOException, GeneralSecurityException { + JobDataMap jobDataMap = new JobDataMap(); + jobDataMap.put(TEMPLATE_NAME, templateName); + jobDataMap.put(VES_URL, vesUrl); + jobDataMap.put(EVENT_ID, eventId); + jobDataMap.put(KEYWORDS_HANDLER, keywordsHandler); + jobDataMap.put(BODY, body); + jobDataMap.put(CLIENT_ADAPTER, new HttpClientAdapterImpl(vesUrl, SSLAuthenticationHelper)); + + return JobBuilder + .newJob(EventJob.class) + .withDescription(templateName) + .usingJobData(jobDataMap) + .build(); + } + + private List<JobKey> getActiveJobsKeys() throws SchedulerException { + return scheduler.getCurrentlyExecutingJobs() + .stream() + .map(JobExecutionContext::getJobDetail) + .map(JobDetail::getKey) + .collect(Collectors.toList()); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/QuartzConfiguration.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/QuartzConfiguration.java new file mode 100644 index 0000000..2beb9dc --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulator/scheduler/QuartzConfiguration.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.scheduler; + +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.impl.StdSchedulerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +class QuartzConfiguration { + + @Bean + Scheduler provideScheduler() throws SchedulerException { + StdSchedulerFactory stdSchedulerFactory = new StdSchedulerFactory(); + Scheduler scheduler = stdSchedulerFactory.getScheduler(); + scheduler.start(); + return scheduler; + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfig.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfig.java new file mode 100644 index 0000000..0baa477 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfig.java @@ -0,0 +1,49 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.simulatorconfig; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Field; + +import javax.validation.constraints.NotNull; +import java.net.URL; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@ToString +public class SimulatorConfig { + + @JsonIgnore + @Id + private String id; + + @NotNull + @Field("vesServerUrl") + private URL vesServerUrl; +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigRepository.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigRepository.java new file mode 100644 index 0000000..5e63ee4 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigRepository.java @@ -0,0 +1,26 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.simulatorconfig; + +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface SimulatorConfigRepository extends MongoRepository<SimulatorConfig, String> { +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigService.java new file mode 100644 index 0000000..2063351 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigService.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.simulatorconfig; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +public class SimulatorConfigService { + + private final SimulatorConfigRepository repository; + + @Autowired + public SimulatorConfigService(SimulatorConfigRepository repository) { + this.repository = repository; + } + + + public SimulatorConfig getConfiguration() { + List<SimulatorConfig> configs = repository.findAll(); + if (configs.isEmpty()) { + throw new IllegalStateException("No configuration found in db"); + } + return configs.get(0); + } + + public SimulatorConfig updateConfiguration(SimulatorConfig configuration) { + SimulatorConfig currentConfig = getConfiguration(); + currentConfig.setVesServerUrl(configuration.getVesServerUrl()); + return repository.save(currentConfig); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java new file mode 100644 index 0000000..881585b --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/FsToDbTemplateSynchronizer.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.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; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class FsToDbTemplateSynchronizer { + + private static final String CANNOT_SYNC = "Cannot synchronize templates. Check whether the proper folder exists."; + private static final Logger LOGGER = LoggerFactory.getLogger(FsToDbTemplateSynchronizer.class); + + private final String templatesDir; + private final Storage<Template> storage; + + @Autowired + public FsToDbTemplateSynchronizer(@Value("${templates.dir}") String templatesDir, + Storage<Template> storage) { + this.templatesDir = templatesDir; + this.storage = storage; + } + + public void synchronize() { + try { + processTemplatesFolder(); + } catch (IOException e) { + LOGGER.error(CANNOT_SYNC, e); + } + } + + private void processTemplatesFolder() throws IOException { + try (Stream<Path> walk = Files.walk(Paths.get(templatesDir))) { + walk.filter(Files::isRegularFile).forEach(path -> { + try { + WatcherEventProcessor.MODIFIED.processEvent(path, storage); + } catch (IOException | JsonParseException e) { + LOGGER + .error("Cannot synchronize template: " + path.getFileName().toString(), e); + } + }); + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/Template.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/Template.java new file mode 100644 index 0000000..c84b8d0 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/Template.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template; + +import java.util.Objects; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.pnfsimulator.db.Row; +import org.bson.Document; +import org.onap.pnfsimulator.template.search.JsonUtils; +import org.springframework.data.mongodb.core.mapping.Field; + +@NoArgsConstructor +@ToString +public class Template extends Row { + + @Field("content") + private Document content; + + @Field("flatContent") + private Document flatContent; + + @Field("lmod") + private long lmod; + + public Template(String name, Document content, long lmod) { + this.id = name; + this.content = content; + this.lmod = lmod; + this.flatContent = new JsonUtils().flatten(content); + } + + public Template(String name, String template, long lmod) { + this.id = name; + this.content = Document.parse(template); + this.lmod = lmod; + this.flatContent = new JsonUtils().flatten(this.content); + } + + public void setContent(Document content) { + this.content = content; + this.flatContent = new JsonUtils().flatten(content); + } + + public Document getContent() { + return new Document(this.content); + } + + @JsonIgnore + public Document getFlatContent() { + return new Document(this.flatContent); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Template template = (Template) o; + return Objects.equals(content, template.content) + && Objects.equals(id, template.id) + && Objects.equals(lmod, template.lmod); + } + + @Override + public int hashCode() { + return Objects.hash(content, id); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateRepository.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateRepository.java new file mode 100644 index 0000000..78c9c77 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateRepository.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template; + +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface TemplateRepository extends MongoRepository<Template, String> { +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateService.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateService.java new file mode 100644 index 0000000..3e245e1 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/TemplateService.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template; + +import java.util.List; +import java.util.Optional; + +import com.google.gson.JsonObject; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.template.search.TemplateSearchHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Service; + +@Primary +@Service +public class TemplateService implements Storage<Template> { + + private final TemplateRepository templateRepository; + private TemplateSearchHelper searchHelper; + + + @Autowired + public TemplateService(TemplateRepository templateRepository, TemplateSearchHelper searchHelper) { + this.templateRepository = templateRepository; + this.searchHelper = searchHelper; + } + + @Override + public List<Template> getAll() { + return templateRepository.findAll(); + } + + @Override + public Optional<Template> get(String name) { + return templateRepository.findById(name); + } + + @Override + public void persist(Template template) { + templateRepository.save(template); + } + + @Override + public boolean tryPersistOrOverwrite(Template template, boolean overwrite) { + if (templateRepository.existsById(template.getId()) && !overwrite) { + return false; + } + templateRepository.save(template); + return true; + } + + @Override + public void delete(String templateName) { + templateRepository.deleteById(templateName); + } + + @Override + public List<String> getIdsByContentCriteria(JsonObject stringQueryJson) { + return searchHelper.getIdsOfDocumentMatchingCriteria(stringQueryJson); + } + +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/IllegalJsonValueException.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/IllegalJsonValueException.java new file mode 100644 index 0000000..6890382 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/IllegalJsonValueException.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search; + +public class IllegalJsonValueException extends IllegalArgumentException { + + IllegalJsonValueException(String s) { + super(s); + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/JsonUtils.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/JsonUtils.java new file mode 100644 index 0000000..b595b4f --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/JsonUtils.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search; + +import com.google.common.base.Strings; +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import org.bson.Document; + +/** + * This util flattens nested json and produces json with keys transformed to form of json path + * where default separator between parent object key and object key is ':' + * For easing searching of boolean values, they are converted to its string representation + */ +public class JsonUtils { + + private static final String DEFAULT_PARENT_KEY_TO_OBJECT_KEY_SEPARATOR = ":"; + private static final String SEED_PREFIX = ""; + private static final Gson GSON = new Gson(); + + public JsonObject flatten(JsonObject original) { + return flattenWithPrefixedKeys(DEFAULT_PARENT_KEY_TO_OBJECT_KEY_SEPARATOR, original.deepCopy(), SEED_PREFIX, new JsonObject()); + } + + public JsonObject flatten(String parentKeyToKeySeparator, JsonObject original) { + return flattenWithPrefixedKeys(parentKeyToKeySeparator, original.deepCopy(), SEED_PREFIX, new JsonObject()); + } + + public Document flatten(Document original) { + return flatten(DEFAULT_PARENT_KEY_TO_OBJECT_KEY_SEPARATOR, original); + } + + public Document flatten(String parentKeyToKeySeparator, Document original) { + JsonObject originalJsonObject = GSON.fromJson(original.toJson(), JsonObject.class); + JsonObject flattenedJson = flatten(parentKeyToKeySeparator, originalJsonObject); + return Document.parse(flattenedJson.toString()); + } + + private JsonObject flattenWithPrefixedKeys(String parentKeyToKeySeparator, JsonElement topLevelElem, String prefix, JsonObject acc) { + if (topLevelElem.isJsonPrimitive()) { + handleJsonPrimitive(topLevelElem, prefix, acc); + } else if (topLevelElem.isJsonArray()) { + handleJsonArray(parentKeyToKeySeparator, topLevelElem, prefix, acc); + } else if (topLevelElem.isJsonObject()) { + handleJsonObject(parentKeyToKeySeparator, topLevelElem, prefix, acc); + } else { + acc.add(prefix, topLevelElem.getAsJsonNull()); + } + return acc.deepCopy(); + } + + private void handleJsonObject(String parentKeyToKeySeparator, JsonElement topLevelElem, String prefix, JsonObject acc) { + boolean isEmpty = true; + JsonObject thisToplevelObj = topLevelElem.getAsJsonObject(); + for (String key : thisToplevelObj.keySet()) { + isEmpty = false; + String keyPrefix = String.format("%s%s%s", prefix, parentKeyToKeySeparator, key); + flattenWithPrefixedKeys(parentKeyToKeySeparator, thisToplevelObj.get(key), keyPrefix, acc); + } + if (isEmpty && !Strings.isNullOrEmpty(prefix)) { + acc.add(prefix, new JsonObject()); + } + } + + private void handleJsonArray(String parentKeyToKeySeparator, JsonElement topLevelElem, String prefix, JsonObject acc) { + JsonArray asJsonArray = topLevelElem.getAsJsonArray(); + if (asJsonArray.size() == 0) { + acc.add(prefix, new JsonArray()); + } + for (int i = 0; i < asJsonArray.size(); i++) { + flattenWithPrefixedKeys(parentKeyToKeySeparator, asJsonArray.get(i), String.format("%s[%s]", prefix, i), acc); + } + } + + private void handleJsonPrimitive(JsonElement topLevelElem, String prefix, JsonObject acc) { + JsonPrimitive jsonPrimitive = topLevelElem.getAsJsonPrimitive(); + if (jsonPrimitive.isBoolean()) { + acc.add(prefix, new JsonPrimitive(jsonPrimitive.getAsString())); + } else { + acc.add(prefix, topLevelElem.getAsJsonPrimitive()); + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/TemplateSearchHelper.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/TemplateSearchHelper.java new file mode 100644 index 0000000..3f22b1a --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/TemplateSearchHelper.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.onap.pnfsimulator.template.search.handler.PrimitiveValueCriteriaBuilder; +import org.onap.pnfsimulator.template.search.viewmodel.FlatTemplateContent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.data.mongodb.core.query.Query; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +@Component +public class TemplateSearchHelper { + private static final String PARENT_TO_CHILD_KEY_SEPARATOR = ":"; //compliant with flat json stored in db + private static final String FLATTENED_JSON_KEY_REGEX = PARENT_TO_CHILD_KEY_SEPARATOR + "%s(?:(\\[[\\d]+\\]))?$"; + private static final String FLATTENED_TEMPLATES_VIEW = "flatTemplatesView"; + + private MongoTemplate mongoTemplate; + private PrimitiveValueCriteriaBuilder criteriaBuilder; + + @Autowired + public TemplateSearchHelper(MongoTemplate mongoTemplate) { + this.mongoTemplate = mongoTemplate; + this.criteriaBuilder = new PrimitiveValueCriteriaBuilder(); + } + + public List<String> getIdsOfDocumentMatchingCriteria(JsonObject jsonCriteria) { + if (isNullValuePresentInCriteria(jsonCriteria)) { + throw new IllegalJsonValueException("Null values in search criteria are not supported."); + } + Criteria mongoDialectCriteria = composeCriteria(jsonCriteria); + Query query = new Query(mongoDialectCriteria); + List<FlatTemplateContent> flatTemplateContents = mongoTemplate.find(query, FlatTemplateContent.class, FLATTENED_TEMPLATES_VIEW); + return flatTemplateContents + .stream() + .map(FlatTemplateContent::getId) + .collect(Collectors.toList()); + } + + + private Criteria composeCriteria(JsonObject criteria) { + Criteria[] criteriaArr = criteria.entrySet() + .stream() + .map(this::mapEntryCriteriaWithRegex) + .toArray(Criteria[]::new); + return criteriaArr.length > 0 ? new Criteria().andOperator(criteriaArr) : new Criteria(); + } + + private Criteria mapEntryCriteriaWithRegex(Map.Entry<String, JsonElement> entry) { + Pattern primitiveOrArrayElemKeyRegex = getCaseInsensitive(String.format(FLATTENED_JSON_KEY_REGEX, entry.getKey())); + Criteria criteriaForJsonKey = Criteria.where("k").regex(primitiveOrArrayElemKeyRegex); + Criteria criteriaWithValue = criteriaBuilder.applyValueCriteriaBasedOnPrimitiveType(criteriaForJsonKey.and("v"), entry.getValue().getAsJsonPrimitive()); + return Criteria.where("keyValues").elemMatch(criteriaWithValue); + + } + + private boolean isNullValuePresentInCriteria(JsonObject jsonObject) { + return jsonObject.entrySet() + .stream() + .map(Map.Entry::getValue) + .anyMatch(JsonElement::isJsonNull); + } + + static Pattern getCaseInsensitive(String base) { + return Pattern.compile(base, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); + } +} + + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilder.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilder.java new file mode 100644 index 0000000..79d64b7 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilder.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search.handler; + +import com.google.common.collect.Lists; +import com.google.gson.JsonPrimitive; +import org.springframework.data.mongodb.core.query.Criteria; + +import java.util.List; +import java.util.regex.Pattern; + +/** + * This class is a helper class for constructing apropriate criteria for query send to mongodb based on type of value. + * Query is build to search mongodb for templates that contains key-value pairs that satisfy given criteria. + * Value is oftype JsonPrimitive, based on its primitive java type following criteria are build to get proper document: + * -for string - there is a regex expression that ignores every meta character inside passed argument and searches for exact literal match ignoring case; + * -for number - all numbers are treated as double (mongodb number type equivalent) + * -for boolean - exact match, used string representation of boolean in search + **/ + +public class PrimitiveValueCriteriaBuilder { + + private final List<ValueTypeHandler> typeHandlers; + + public PrimitiveValueCriteriaBuilder() { + typeHandlers = Lists.newArrayList(new StringValueHandler(), new NumberValueHandler(), new BoolValueHandler()); + } + + public Criteria applyValueCriteriaBasedOnPrimitiveType(Criteria baseCriteria, JsonPrimitive jsonPrimitive) { + ValueTypeHandler typeHandler = typeHandlers.stream() + .filter(el -> el.isProperTypeHandler(jsonPrimitive)) + .findFirst() + .orElseThrow(() -> + new IllegalArgumentException(String.format( + "Expected json primitive, but given value: %s is of type: %s and could not be decoded", + jsonPrimitive, jsonPrimitive.getClass().toString()))); + return typeHandler.chainCriteriaForValue(baseCriteria, jsonPrimitive); + } + + private interface ValueTypeHandler { + boolean isProperTypeHandler(JsonPrimitive value); + + Criteria chainCriteriaForValue(Criteria criteria, JsonPrimitive value); + } + + private class BoolValueHandler implements ValueTypeHandler { + public boolean isProperTypeHandler(JsonPrimitive value) { + return value.isBoolean(); + } + + public Criteria chainCriteriaForValue(Criteria criteria, JsonPrimitive value) { + return criteria.is(value.getAsString()); + } + + } + + private class NumberValueHandler implements ValueTypeHandler { + public boolean isProperTypeHandler(JsonPrimitive value) { + return value.isNumber(); + } + + public Criteria chainCriteriaForValue(Criteria baseCriteria, JsonPrimitive value) { + return baseCriteria.is(value.getAsDouble()); + } + } + + private class StringValueHandler implements ValueTypeHandler { + public boolean isProperTypeHandler(JsonPrimitive value) { + return value.isString(); + } + + public Criteria chainCriteriaForValue(Criteria baseCriteria, JsonPrimitive value) { + return baseCriteria.regex(makeRegexCaseInsensitive(value.getAsString())); + } + + private Pattern makeRegexCaseInsensitive(String base) { + String metaCharEscaped = convertToIgnoreMetaChars(base); + return Pattern.compile("^" + metaCharEscaped + "$", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE); + } + + private String convertToIgnoreMetaChars(String valueWithMetaChars) { + return Pattern.quote(valueWithMetaChars); + } + } +} diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/FlatTemplateContent.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/FlatTemplateContent.java new file mode 100644 index 0000000..84235f7 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/FlatTemplateContent.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search.viewmodel; + + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; +import org.onap.pnfsimulator.db.Row; + +import java.util.List; + +@Getter +@NoArgsConstructor +@ToString +public class FlatTemplateContent extends Row { + + private List<KeyValuePair> keyValues; + + + public FlatTemplateContent(String name, List<KeyValuePair> keyValues) { + this.id = name; + this.keyValues = keyValues; + } +} + + diff --git a/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/KeyValuePair.java b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/KeyValuePair.java new file mode 100644 index 0000000..5e44452 --- /dev/null +++ b/pnfsimulator/src/main/java/org/onap/pnfsimulator/template/search/viewmodel/KeyValuePair.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search.viewmodel; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Getter +@ToString +@NoArgsConstructor +@AllArgsConstructor +/** + * POJO for mongo structure after $objectToArray mapping where object consists of fields: k and v + */ +public class KeyValuePair { + + private String k; + private String v; + +} diff --git a/pnfsimulator/src/main/resources/application.properties b/pnfsimulator/src/main/resources/application.properties new file mode 100644 index 0000000..e2c7639 --- /dev/null +++ b/pnfsimulator/src/main/resources/application.properties @@ -0,0 +1,18 @@ +server.port=5000 +templates.dir=/app/templates +spring.data.mongodb.host=mongo +spring.data.mongodb.port=27017 +spring.data.mongodb.username=pnf_simulator_user +spring.data.mongodb.password=zXcVbN123! +spring.data.mongodb.database=pnf_simulator +management.endpoints.enabled-by-default=true +management.endpoint.configprops.enabled=true +management.endpoints.web.base-path=/ +management.server.port=5001 +management.endpoints.web.exposure.include=refresh + +ssl.clientCertificateEnabled=true +ssl.clientCertificateDir=/app/store/client.p12 +ssl.clientCertificatePassword=collector +ssl.trustStoreDir=/app/store/trustStore +ssl.trustStorePassword=collector diff --git a/pnfsimulator/src/main/resources/logback.xml b/pnfsimulator/src/main/resources/logback.xml new file mode 100644 index 0000000..8569b56 --- /dev/null +++ b/pnfsimulator/src/main/resources/logback.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Simulator + ================================================================================ + Copyright (C) 2019 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========================================================= + --> + +<Configuration complete="true" compact="true"> + + <Property name="outputFilename" value="pnfsimulator_output"/> + <Property name="log-path" value="/var/log/ONAP/pnfsimulator"/> + <Property name="archive" value="/var/log/ONAP/pnfsimulator/archive"/> + <property name="maxFileSize" value="50MB"/> + <property name="maxHistory" value="30"/> + <property name="totalSizeCap" value="10GB"/> + + <appender name="Console" target="SYSTEM_OUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%nopexception%logger + |%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} + |%level + |%replace(%replace(%message){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%rootException){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%marker){'\t','\\\\t'}){'\n','\\\\n'} + |%thread + |%n</Pattern> + </encoder> + </appender> + + <appender name="ROLLING-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <encoder> + <pattern>%nopexception%logger + |%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} + |%level + |%replace(%replace(%message){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%rootException){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%marker){'\t','\\\\t'}){'\n','\\\\n'} + |%thread + |%n</pattern> + </encoder> + <File>${log-path}/${outputFilename}.log</File> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <FileNamePattern>${archive}/${outputFilename}.%d{yyyy-MM-dd}.%i.log.zip</FileNamePattern> + <MaxFileSize>${maxFileSize}</MaxFileSize> + <MaxHistory>${maxHistory}</MaxHistory> + <TotalSizeCap>${totalSizeCap}</TotalSizeCap> + </rollingPolicy> + </appender> + + <root level="info"> + <appender-ref ref="Console" /> + <appender-ref ref="ROLLING-FILE" /> + </root> +</Configuration> diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/event/EventDataServiceTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/event/EventDataServiceTest.java new file mode 100644 index 0000000..5ed51cc --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/event/EventDataServiceTest.java @@ -0,0 +1,133 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.event; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.hamcrest.collection.IsIterableContainingInOrder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeEach; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +public class EventDataServiceTest { + + @Mock + private EventDataRepository repositoryMock; + + @InjectMocks + private EventDataService service; + + private static EventData sampleEventData(String id, String template, + String patched, String input, String keywords) { + return EventData.builder() + .id(id) + .template(template) + .patched(patched) + .input(input) + .keywords(keywords) + .build(); + } + + @BeforeEach + void resetMocks() { + initMocks(this); + } + + @Test + void persistEventDataJsonObjectTest() { + JsonParser parser = new JsonParser(); + JsonObject template = parser.parse("{ \"bla1\": \"bla2\"}").getAsJsonObject(); + JsonObject patched = parser.parse("{ \"bla3\": \"bla4\"}").getAsJsonObject(); + JsonObject input = parser.parse("{ \"bla5\": \"bla6\"}").getAsJsonObject(); + JsonObject keywords = parser.parse("{ \"bla7\": \"bla8\"}").getAsJsonObject(); + ArgumentCaptor<EventData> argumentCaptor = ArgumentCaptor.forClass(EventData.class); + + service.persistEventData(template, patched, input, keywords); + + verify(repositoryMock).save(argumentCaptor.capture()); + EventData captured = argumentCaptor.getValue(); + + assertEquals(captured.getTemplate(), template.toString()); + assertEquals(captured.getPatched(), patched.toString()); + assertEquals(captured.getInput(), input.toString()); + assertEquals(captured.getKeywords(), keywords.toString()); + } + + @Test + void getAllEventsTest() { + + List<EventData> eventDataList = new ArrayList<>(); + EventData ed1 = sampleEventData("id1", "t1", "p1", "i1", "k1"); + EventData ed2 = sampleEventData("id2", "t2", "p2", "i2", "k2"); + eventDataList.add(ed1); + eventDataList.add(ed2); + + when(repositoryMock.findAll()).thenReturn(eventDataList); + List<EventData> actualList = service.getAllEvents(); + + assertEquals(eventDataList.size(), actualList.size()); + assertThat(actualList, IsIterableContainingInOrder.contains(ed1, ed2)); + } + + @Test + void findByIdPresentTest() { + String id = "some_object"; + EventData eventData = sampleEventData(id, "template", "patched", "input", "keywords"); + Optional<EventData> optional = Optional.of(eventData); + + when(repositoryMock.findById(id)).thenReturn(optional); + + Optional<EventData> actualOptional = service.getById(id); + assertTrue(actualOptional.isPresent()); + EventData actualObject = actualOptional.get(); + assertEquals(eventData.getId(), actualObject.getId()); + assertEquals(eventData.getTemplate(), actualObject.getTemplate()); + assertEquals(eventData.getPatched(), actualObject.getPatched()); + assertEquals(eventData.getInput(), actualObject.getInput()); + assertEquals(eventData.getKeywords(), actualObject.getKeywords()); + + } + + @Test + void findByIdNotPresentTest() { + String id = "some_object"; + Optional<EventData> optional = Optional.empty(); + + when(repositoryMock.findById(id)).thenReturn(optional); + + Optional<EventData> actualOptional = service.getById(id); + assertTrue(!actualOptional.isPresent()); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/InMemoryTemplateStorage.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/InMemoryTemplateStorage.java new file mode 100644 index 0000000..98c4bc5 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/InMemoryTemplateStorage.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import com.google.gson.JsonObject; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.template.Template; + +public class InMemoryTemplateStorage implements Storage<Template> { + + private List<Template> storage = new ArrayList<>(); + + @Override + public List<Template> getAll() { + return new ArrayList<>(storage); + } + + @Override + public Optional<Template> get(String name) { + return storage.stream().filter(template -> template.getId().equals(name)).findFirst(); + } + + @Override + public void persist(Template template) { + if (!storage.contains(template)){ + storage.add(template); + } + } + + @Override + public boolean tryPersistOrOverwrite(Template template, boolean overwrite) { + if (!storage.contains(template) || overwrite){ + storage.add(template); + return true; + } + return false; + } + + @Override + public void delete(String templateName) { + get(templateName).ifPresent(template -> storage.remove(template)); + } + + @Override + public List<String> getIdsByContentCriteria(JsonObject queryJson) { + throw new RuntimeException("Method is not implemented."); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessorTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessorTest.java new file mode 100644 index 0000000..42ed4d3 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/filesystem/WatcherEventProcessorTest.java @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.filesystem; + +import static junit.framework.TestCase.fail; +import static org.mockito.MockitoAnnotations.initMocks; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardWatchEventKinds; +import java.nio.file.WatchEvent; +import java.time.Instant; +import java.util.Collections; +import java.util.HashMap; +import java.util.Optional; +import org.bson.Document; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.template.Template; + +class WatcherEventProcessorTest { + + @Mock + private WatchEvent watchEvent; + @Mock + private Path templatesDir; + + private Storage<Template> storage; + private static Path jsonFilePath; + + @BeforeAll + static void init() { + jsonFilePath = Paths.get("src/test/resources/org/onap/pnfsimulator/simulator/filesystem/test1.json"); + } + + @BeforeEach + void resetMocks() { + initMocks(this); + storage = new InMemoryTemplateStorage(); + initStubs(); + } + + @Test + void shouldProcessCreatedEventTest() { + // when + Mockito.when(watchEvent.kind()).thenReturn(StandardWatchEventKinds.ENTRY_CREATE); + WatcherEventProcessor.process(watchEvent, storage, templatesDir); + // then + verifyPersistedValue(); + } + + @Test + void shouldProcessModifiedEventTest() { + //given + storage.persist(new Template("test1.json", new Document(Collections.emptyMap()), Instant.now().getNano())); + // when + Mockito.when(watchEvent.kind()).thenReturn(StandardWatchEventKinds.ENTRY_MODIFY); + WatcherEventProcessor.process(watchEvent, storage, templatesDir); + // then + verifyPersistedValue(); + } + + private void verifyPersistedValue() { + Assertions.assertEquals(storage.getAll().size(), 1); + Optional<Template> templateFromStorage = storage.get("test1.json"); + if (templateFromStorage.isPresent()) { + Template retrievedTemplate = templateFromStorage.get(); + Document templateContent = retrievedTemplate.getContent(); + Document flatContent = retrievedTemplate.getFlatContent(); + Assertions.assertEquals(templateContent.getString("field1"), "value1"); + Assertions.assertEquals(templateContent.getInteger("field2", 0), 2); + Assertions.assertEquals(flatContent.getInteger(":nested:key1[0]", 0), 1); + Assertions.assertEquals(flatContent.getInteger(":nested:key1[1]", 0), 2); + Assertions.assertEquals(flatContent.getInteger(":nested:key1[2]", 0), 3); + Assertions.assertEquals(flatContent.getString(":nested:key2"), "sampleValue2"); + } else { + fail(); + } + } + + @Test + void shouldProcessDeletedEventTest() { + //given + HashMap<String, Object> legacyObject = new HashMap<>(); + legacyObject.put("field1", "value1"); + legacyObject.put("field2", 2); + + storage.persist(new Template("test1.json", new Document(legacyObject), Instant.now().getNano())); + // when + Mockito.when(watchEvent.kind()).thenReturn(StandardWatchEventKinds.ENTRY_DELETE); + WatcherEventProcessor.process(watchEvent, storage, templatesDir); + // then + Assertions.assertEquals(storage.getAll().size(), 0); + } + + private void initStubs() { + Mockito.when(templatesDir.resolve(jsonFilePath)).thenReturn(jsonFilePath); + Mockito.when(watchEvent.context()).thenReturn(jsonFilePath); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java new file mode 100644 index 0000000..dae16c7 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/SimulatorControllerTest.java @@ -0,0 +1,212 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +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.rest.util.JsonObjectDeserializer; +import org.onap.pnfsimulator.simulator.SimulatorService; +import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig; +import org.quartz.SchedulerException; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.result.MockMvcResultHandlers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import java.io.IOException; +import java.net.URL; +import java.security.GeneralSecurityException; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +class SimulatorControllerTest { + + private static final String START_ENDPOINT = "/simulator/start"; + private static final String CONFIG_ENDPOINT = "/simulator/config"; + private static final String EVENT_ENDPOINT = "/simulator/event"; + private static final String JSON_MSG_EXPRESSION = "$.message"; + + private static final String NEW_URL = "http://0.0.0.0:8090/eventListener/v7"; + private static final String UPDATE_SIM_CONFIG_VALID_JSON = "{\"vesServerUrl\": \"" + NEW_URL + "\"}"; + private static final String SAMPLE_ID = "sampleId"; + private static final Gson GSON_OBJ = new Gson(); + private static String simulatorRequestBody; + private MockMvc mockMvc; + @InjectMocks + private SimulatorController controller; + @Mock + private SimulatorService simulatorService; + + @BeforeAll + static void beforeAll() { + SimulatorParams simulatorParams = new SimulatorParams("http://0.0.0.0:8080", 1, 1); + SimulatorRequest simulatorRequest = new SimulatorRequest(simulatorParams, + "testTemplate.json", new JsonObject()); + + simulatorRequestBody = GSON_OBJ.toJson(simulatorRequest); + } + + @BeforeEach + void setup() throws IOException, SchedulerException, GeneralSecurityException { + MockitoAnnotations.initMocks(this); + when(simulatorService.triggerEvent(any())).thenReturn("jobName"); + mockMvc = MockMvcBuilders + .standaloneSetup(controller) + .build(); + } + + @Test + void shouldStartSimulatorProperly() throws Exception { + startSimulator(); + SimulatorRequest simulatorRequest = new Gson().fromJson(simulatorRequestBody, SimulatorRequest.class); + + verify(simulatorService).triggerEvent(eq(simulatorRequest)); + } + + @Test + void testShouldGetConfigurationWhenRequested() throws Exception { + String newUrl = "http://localhost:8090/eventListener/v7"; + SimulatorConfig expectedConfig = new SimulatorConfig(SAMPLE_ID, new URL(newUrl)); + when(simulatorService.getConfiguration()).thenReturn(expectedConfig); + + MvcResult getResult = mockMvc + .perform(get(CONFIG_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON) + .content(UPDATE_SIM_CONFIG_VALID_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String expectedVesUrlJsonPart = createStringReprOfJson("vesServerUrl", newUrl); + assertThat(getResult.getResponse().getContentAsString()).contains(expectedVesUrlJsonPart); + } + + @Test + void testShouldSuccessfullyUpdateConfigurationWithNewVesUrl() throws Exception { + String oldUrl = "http://localhost:8090/eventListener/v7"; + SimulatorConfig expectedConfigBeforeUpdate = new SimulatorConfig(SAMPLE_ID, new URL(oldUrl)); + SimulatorConfig expectedConfigAfterUpdate = new SimulatorConfig(SAMPLE_ID, new URL(NEW_URL)); + + when(simulatorService.getConfiguration()).thenReturn(expectedConfigBeforeUpdate); + when(simulatorService.updateConfiguration(any(SimulatorConfig.class))).thenReturn(expectedConfigAfterUpdate); + + MvcResult postResult = mockMvc + .perform(put(CONFIG_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON) + .content(UPDATE_SIM_CONFIG_VALID_JSON)) + .andExpect(status().isOk()) + .andReturn(); + + String expectedVesUrlJsonPart = createStringReprOfJson("vesServerUrl", expectedConfigAfterUpdate.getVesServerUrl().toString()); + assertThat(postResult.getResponse().getContentAsString()).contains(expectedVesUrlJsonPart); + } + + @Test + void testShouldRaiseExceptionWhenUpdateConfigWithIncorrectPayloadWasSent() throws Exception { + mockMvc + .perform(put(CONFIG_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"vesUrl\": \"" + NEW_URL + "\"}")) + .andExpect(status().isBadRequest()); + } + + @Test + void testShouldRaiseExceptionWhenUrlInInvalidFormatIsSent() throws Exception { + mockMvc + .perform(put(CONFIG_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"vesUrl\": \"http://0.0.0.0:VES-PORT/eventListener/v7\"}")) + .andExpect(status().isBadRequest()); + } + + @Test + void testShouldSendEventDirectly() throws Exception { + String contentAsString = mockMvc + .perform(post(EVENT_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content("{\"vesServerUrl\":\"http://0.0.0.0:8080/simulator/v7\",\n" + + " \"event\":{ \n" + + " \"commonEventHeader\":{ \n" + + " \"domain\":\"notification\",\n" + + " \"eventName\":\"vFirewallBroadcastPackets\"\n" + + " },\n" + + " \"notificationFields\":{ \n" + + " \"arrayOfNamedHashMap\":[ \n" + + " { \n" + + " \"name\":\"A20161221.1031-1041.bin.gz\",\n" + + " \"hashMap\":{ \n" + + " \"fileformatType\":\"org.3GPP.32.435#measCollec\"}}]}}}")) + .andExpect(status().isAccepted()).andReturn().getResponse().getContentAsString(); + assertThat(contentAsString).contains("One-time direct event sent successfully"); + } + + @Test + void testShouldReplaceKeywordsAndSendEventDirectly() throws Exception { + String contentAsString = mockMvc + .perform(post(EVENT_ENDPOINT) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content("{\"vesServerUrl\": \"http://localhost:9999/eventListener\",\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"eventId\": \"#RandomString(20)\",\n" + + " \"sourceName\": \"PATCHED_sourceName\",\n" + + " \"version\": 3.0\n}}}")) + .andExpect(status().isAccepted()).andReturn().getResponse().getContentAsString(); + assertThat(contentAsString).contains("One-time direct event sent successfully"); + + verify(simulatorService, Mockito.times(1)).triggerOneTimeEvent(any(FullEvent.class)); + } + + + private void startSimulator() throws Exception { + mockMvc + .perform(post(START_ENDPOINT) + .content(simulatorRequestBody) + .contentType(MediaType.APPLICATION_JSON).characterEncoding("utf-8")) + .andExpect(status().isOk()) + .andExpect(jsonPath(JSON_MSG_EXPRESSION).value("Request started")); + + } + + private String createStringReprOfJson(String key, String value) { + return GSON_OBJ.toJson(ImmutableMap.of(key, value)); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/TemplateControllerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/TemplateControllerTest.java new file mode 100644 index 0000000..f34d73c --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/TemplateControllerTest.java @@ -0,0 +1,256 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.rest; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.onap.pnfsimulator.rest.TemplateController.CANNOT_OVERRIDE_TEMPLATE_MSG; +import static org.onap.pnfsimulator.rest.TemplateController.TEMPLATE_NOT_FOUND_MSG; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import org.assertj.core.util.Lists; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import static org.mockito.Mockito.times; +import org.mockito.MockitoAnnotations; +import org.onap.pnfsimulator.db.Storage; +import org.onap.pnfsimulator.rest.model.SearchExp; +import org.onap.pnfsimulator.template.Template; +import org.onap.pnfsimulator.template.search.IllegalJsonValueException; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +class TemplateControllerTest { + + private static final String LIST_URL = "/template/list"; + private static final String GET_FORMAT_STR = "/template/get/%s"; + private static final String SEARCH_ENDPOINT = "/template/search"; + private static final String UPLOAD_URL_NOFORCE = "/template/upload"; + private static final String UPLOAD_URL_FORCE = "/template/upload?override=true"; + private static final String SAMPLE_TEMPLATE_JSON = "{\"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"measurementsForVfScaling\",\n" + + " \"eventName\": \"vFirewallBroadcastPackets\",\n" + + " }" + + "}}"; + + public static final String TEMPLATE_REQUEST = "{\n" + + " \"name\": \"someTemplate\",\n" + + " \"template\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"notification\",\n" + + " \"eventName\": \"vFirewallBroadcastPackets\"\n" + + " },\n" + + " \"notificationFields\": {\n" + + " \"arrayOfNamedHashMap\": [{\n" + + " \"name\": \"A20161221.1031-1041.bin.gz\",\n" + + "\n" + + " \"hashMap\": {\n" + + " \"fileformatType\": \"org.3GPP.32.435#measCollec\"\n" + + " }\n" + + " }]\n" + + " }\n" + + " }\n" + + "}"; + private static final Document SAMPLE_TEMPLATE_BSON = Document.parse(SAMPLE_TEMPLATE_JSON); + private static final List<String> SAMPLE_TEMPLATE_NAME_LIST = Lists.newArrayList("notification.json", "registration.json"); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + private static final Gson GSON_OBJ = new GsonBuilder().create(); + private MockMvc mockMvc; + + @Mock + private Storage<Template> templateService; + @InjectMocks + private TemplateController controller; + + @BeforeEach + void setup() { + MockitoAnnotations.initMocks(this); + mockMvc = MockMvcBuilders + .standaloneSetup(controller) + .build(); + } + + @Test + void shouldGetAllTemplates() throws Exception { + List<Template> templateList = createTemplatesList(); + when(templateService.getAll()).thenReturn(templateList); + + MvcResult getResult = mockMvc + .perform(get(LIST_URL) + .accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andReturn(); + + Type listType = new TypeToken<ArrayList<Template>>() {}.getType(); + List<Template> resultList = GSON_OBJ.fromJson(getResult.getResponse().getContentAsString(), listType); + assertThat(resultList).containsExactlyInAnyOrderElementsOf(templateList); + } + + @Test + void shouldListEmptyCollectionWhenNoTemplatesAvailable() throws Exception { + List<Template> templateList = Collections.emptyList(); + when(templateService.getAll()).thenReturn(templateList); + + MvcResult getResult = mockMvc + .perform(get(LIST_URL)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andReturn(); + + String templatesAsString = GSON_OBJ.toJson(templateList); + assertThat(getResult.getResponse().getContentAsString()).containsSequence(templatesAsString); + } + + @Test + void shouldSuccessfullyGetExisitngTemplateByName() throws Exception { + String sampleTemplateName = "someTemplate"; + String requestUrl = String.format(GET_FORMAT_STR, sampleTemplateName); + Template sampleTemplate = new Template(sampleTemplateName, SAMPLE_TEMPLATE_BSON, 0L); + + when(templateService.get(sampleTemplateName)).thenReturn(Optional.of(sampleTemplate)); + + MvcResult getResult = mockMvc + .perform(get(requestUrl)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andReturn(); + + Template result = new Gson().fromJson(getResult.getResponse().getContentAsString(), Template.class); + assertThat(result).isEqualTo(sampleTemplate); + } + + @Test + void shouldReturnNotFoundWhenGetNonExisitngTemplateByName() throws Exception { + String sampleTemplateName = "doesNotExist"; + String requestUrl = String.format(GET_FORMAT_STR, sampleTemplateName); + + when(templateService.get(sampleTemplateName)).thenReturn(Optional.empty()); + + MvcResult getResult = mockMvc + .perform(get(requestUrl)) + .andExpect(status().isNotFound()) + .andExpect(content().contentType(MediaType.TEXT_PLAIN_VALUE)) + .andReturn(); + + assertThat(getResult.getResponse().getContentLength()).isEqualTo(TEMPLATE_NOT_FOUND_MSG.length()); + } + + + @Test + void shouldReturnNamesOfTemplatesThatSatisfyGivenCriteria() throws Exception { + when(templateService.getIdsByContentCriteria(any(JsonObject.class))).thenReturn(SAMPLE_TEMPLATE_NAME_LIST); + SearchExp expr = new SearchExp(new JsonObject()); + + String responseContent = mockMvc + .perform(post(SEARCH_ENDPOINT).content(GSON_OBJ.toJson(expr)).contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andReturn().getResponse().getContentAsString(); + + List<String> actualTemplates = OBJECT_MAPPER.readValue(responseContent, new TypeReference<List<String>>() {}); + verify(templateService, times(1)).getIdsByContentCriteria(any(JsonObject.class)); + assertThat(actualTemplates).isEqualTo(SAMPLE_TEMPLATE_NAME_LIST); + } + + @Test + void shouldRaiseBadRequestWhenNullValueProvidedInSearchJsonAsJsonValue() throws Exception { + when(templateService.getIdsByContentCriteria(any(JsonObject.class))).thenThrow(IllegalJsonValueException.class); + SearchExp expr = new SearchExp(new JsonObject()); + + mockMvc.perform(post(SEARCH_ENDPOINT) + .content(GSON_OBJ.toJson(expr)) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)) + .andExpect(status().isBadRequest()); + } + + + @Test + void testTryUploadNewTemplate() throws Exception { + when(templateService.tryPersistOrOverwrite(any(Template.class), eq(false))).thenReturn(true); + + MvcResult postResult = mockMvc + .perform(post(UPLOAD_URL_NOFORCE) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content(TEMPLATE_REQUEST)) + .andExpect(status().isCreated()) + .andReturn(); + } + + @Test + void testTryUploadNewTemplateWithForce() throws Exception { + when(templateService.tryPersistOrOverwrite(any(Template.class), eq(true))).thenReturn(true); + + MvcResult postResult = mockMvc + .perform(post(UPLOAD_URL_FORCE) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content(TEMPLATE_REQUEST)) + .andExpect(status().isCreated()) + .andReturn(); + } + + @Test + void testOverrideExistingTemplateWithoutForceShouldFail() throws Exception { + when(templateService.tryPersistOrOverwrite(any(Template.class), eq(true))).thenReturn(false); + + MvcResult postResult = mockMvc + .perform(post(UPLOAD_URL_FORCE) + .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) + .content(TEMPLATE_REQUEST)) + .andExpect(status().isConflict()) + .andReturn(); + + assertThat(postResult.getResponse().getContentAsString()).isEqualTo(CANNOT_OVERRIDE_TEMPLATE_MSG); + } + + private List<Template> createTemplatesList() { + return Arrays.asList( + new Template("1", SAMPLE_TEMPLATE_BSON, 0L), + new Template("2", SAMPLE_TEMPLATE_BSON, 0L), + new Template("3", SAMPLE_TEMPLATE_BSON, 0L)); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/DateUtilTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/DateUtilTest.java new file mode 100644 index 0000000..1591a59 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/DateUtilTest.java @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import org.junit.jupiter.api.Test; + +class DateUtilTest { + + @Test + void getFormattedDate() { + Calendar currentCalendar = Calendar.getInstance(); + String expectedResult = String.valueOf(currentCalendar.get(Calendar.YEAR)); + + assertEquals(expectedResult, DateUtil.getTimestamp(new SimpleDateFormat("yyyy"))); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/ResponseBuilderTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/ResponseBuilderTest.java new file mode 100644 index 0000000..0d62ee9 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/rest/util/ResponseBuilderTest.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.rest.util; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +class ResponseBuilderTest { + + + private static final HttpStatus SAMPLE_STATUS = HttpStatus.OK; + + @Test + void response_should_have_empty_body_when_built_immediately() { + ResponseEntity responseEntity = ResponseBuilder.status(SAMPLE_STATUS).build(); + + assertAll( + () -> assertEquals(responseEntity.getStatusCode(), SAMPLE_STATUS), + () -> assertNull(responseEntity.getBody()) + ); + } + + @Test + void builder_should_set_response_status_and_body() { + String key = "key"; + String value = "value"; + ResponseEntity response = ResponseBuilder + .status(SAMPLE_STATUS) + .put(key, value) + .build(); + + Map<String, Object> body = (Map<String, Object>) response.getBody(); + + assertAll( + () -> assertEquals(SAMPLE_STATUS, response.getStatusCode()), + () -> assertEquals(value, body.get(key)) + ); + } + + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/IncrementProviderImplTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/IncrementProviderImplTest.java new file mode 100644 index 0000000..53f02da --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/IncrementProviderImplTest.java @@ -0,0 +1,78 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.onap.pnfsimulator.event.EventData; +import org.onap.pnfsimulator.event.EventDataRepository; + +public class IncrementProviderImplTest { + private IncrementProvider incrementProvider; + + @Mock + private EventDataRepository eventDataRepositoryMock; + + @BeforeEach + void setUp() { + eventDataRepositoryMock = mock(EventDataRepository.class); + incrementProvider = new IncrementProviderImpl(eventDataRepositoryMock); + } + + @Test + public void getAndIncrementTest() { + ArgumentCaptor<EventData> eventDataArgumentCaptor = ArgumentCaptor.forClass(EventData.class); + String eventId = "1"; + int initialIncrementValue = 0; + int expectedValue = initialIncrementValue + 1; + EventData eventData = EventData.builder().id(eventId).incrementValue(initialIncrementValue).build(); + Optional<EventData> optional = Optional.of(eventData); + + when(eventDataRepositoryMock.findById(eventId)).thenReturn(optional); + + int value = incrementProvider.getAndIncrement(eventId); + + verify(eventDataRepositoryMock).save(eventDataArgumentCaptor.capture()); + + assertThat(value).isEqualTo(expectedValue); + assertThat(eventDataArgumentCaptor.getValue().getIncrementValue()).isEqualTo(expectedValue); + + } + + @Test + public void shouldThrowOnNonExistingEvent() { + Optional<EventData> emptyOptional = Optional.empty(); + String nonExistingEventId = "THIS_DOES_NOT_EXIST"; + when(eventDataRepositoryMock.findById(nonExistingEventId)).thenReturn(emptyOptional); + + assertThrows(EventNotFoundException.class, + () -> incrementProvider.getAndIncrement(nonExistingEventId)); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomIntegerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomIntegerTest.java new file mode 100644 index 0000000..8198e95 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomIntegerTest.java @@ -0,0 +1,67 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorInvalidRandomIntegerTest { + + private final String keyword; + private KeywordsExtractor keywordsExtractor; + + private static final Collection INVALID_INTEGER_KEYWORDS = Arrays.asList(new Object[][]{ + {"#RandoInteger"}, + {"#Randominteger(23,11)"}, + {"#randomInteger(11,34)"}, + {"#Random_Integer(11,13)"}, + {"#RandomInteger(11)"}, + {"RandomInteger(11)"}, + {"RandomInteger"} + }); + + public KeywordsExtractorInvalidRandomIntegerTest(String keyword) { + this.keyword = keyword; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return INVALID_INTEGER_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substituteStringKeyword(this.keyword, 1), this.keyword); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomStringTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomStringTest.java new file mode 100644 index 0000000..6834c0d --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidRandomStringTest.java @@ -0,0 +1,67 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorInvalidRandomStringTest { + + private final String keyword; + private KeywordsExtractor keywordsExtractor; + + private static final Collection INVALID_STRING_KEYWORDS = Arrays.asList(new Object[][]{ + {"#RandoString"}, + {"#Randomstring(23)"}, + {"#randomString(11)"}, + {"#Random_String(11)"}, + {"#RandomString(11,10)"}, + {"RandomString(11)"}, + {"RandomString"} + }); + + public KeywordsExtractorInvalidRandomStringTest(String keyword) { + this.keyword = keyword; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return INVALID_STRING_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substituteStringKeyword(this.keyword, 1).length(), this.keyword.length()); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidTimestampTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidTimestampTest.java new file mode 100644 index 0000000..eda4070 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorInvalidTimestampTest.java @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorInvalidTimestampTest { + + private final String keyword; + private KeywordsExtractor keywordsExtractor; + + private static final Collection INVALID_TIMESTAMP_KEYWORDS = Arrays.asList(new Object[][]{ + {"#Timesamp"}, + {"#Timestamp(10)"}, + {"#timestamp"}, + {"#Timestamp(11,13)"}, + {"Timestamp"} + }); + + public KeywordsExtractorInvalidTimestampTest(String keyword) { + this.keyword = keyword; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return INVALID_TIMESTAMP_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substituteStringKeyword(this.keyword, 1), this.keyword); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomIntegerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomIntegerTest.java new file mode 100644 index 0000000..be79488 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomIntegerTest.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorValidRandomIntegerTest { + + private final String keyword; + private final String shouldParseTo; + private KeywordsExtractor keywordsExtractor; + + private static final Collection VALID_INTEGER_KEYWORDS = Arrays.asList(new Object[][]{ + {"#RandomInteger(23,23)", "23"}, + {"#RandomInteger(6, 6)12", "612"}, + {"1#RandomInteger(11,11)", "111"}, + {"1#RandomInteger(11,11)2", "1112"} + }); + + public KeywordsExtractorValidRandomIntegerTest(String keyword, String shouldParseTo) { + this.keyword = keyword; + this.shouldParseTo = shouldParseTo; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return VALID_INTEGER_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substituteStringKeyword(this.keyword, 1), this.shouldParseTo); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomPrimitiveIntegerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomPrimitiveIntegerTest.java new file mode 100644 index 0000000..0843ad1 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomPrimitiveIntegerTest.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorValidRandomPrimitiveIntegerTest { + + private final String keyword; + private final Integer shouldParseTo; + private KeywordsExtractor keywordsExtractor; + + private static final Collection VALID_INTEGER_KEYWORDS = Arrays.asList(new Object[][]{ + {"#RandomPrimitiveInteger(23,23)", 23}, + {"#RandomPrimitiveInteger(6, 6)12", 6}, + {"1#RandomPrimitiveInteger(11,11)", 11}, + {"1#RandomPrimitiveInteger(11,11)2", 11} + }); + + public KeywordsExtractorValidRandomPrimitiveIntegerTest(String keyword, Integer shouldParseTo) { + this.keyword = keyword; + this.shouldParseTo = shouldParseTo; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return VALID_INTEGER_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substitutePrimitiveKeyword(this.keyword), Long.valueOf(this.shouldParseTo)); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomStringTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomStringTest.java new file mode 100644 index 0000000..f0fdc0f --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidRandomStringTest.java @@ -0,0 +1,69 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.DEFAULT_STRING_LENGTH; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorValidRandomStringTest { + + private final String keyword; + private final int length; + private KeywordsExtractor keywordsExtractor; + + private static final Collection VALID_STRING_KEYWORDS = Arrays.asList(new Object[][]{ + {"#RandomString", DEFAULT_STRING_LENGTH}, + {"1#RandomString2", 1 + DEFAULT_STRING_LENGTH + 1}, + {"#RandomString(23)", 23}, + {"#RandomString(11)12", 11 + 2}, + {"1#RandomString(11)", 1 + 11}, + {"1#RandomString(11)2", 1 + 11 + 1} + }); + + public KeywordsExtractorValidRandomStringTest(String keyword, int length) { + this.keyword = keyword; + this.length = length; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return VALID_STRING_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + assertEquals(keywordsExtractor.substituteStringKeyword(this.keyword, 1).length(), this.length); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampPrimitiveTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampPrimitiveTest.java new file mode 100644 index 0000000..7743e55 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampPrimitiveTest.java @@ -0,0 +1,66 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2019 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; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.time.Instant; +import java.util.Arrays; +import java.util.Collection; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(Parameterized.class) +public class KeywordsExtractorValidTimestampPrimitiveTest { + private final String keyword; + private KeywordsExtractor keywordsExtractor; + + private static final Collection VALID_TIMESTAMP_KEYWORDS = Arrays.asList(new Object[][]{ + {"#TimestampPrimitive"} + }); + + public KeywordsExtractorValidTimestampPrimitiveTest(String keyword) { + this.keyword = keyword; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return VALID_TIMESTAMP_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + long currentTimestamp = Instant.now().getEpochSecond(); + Long timestamp = keywordsExtractor.substitutePrimitiveKeyword(this.keyword); + long afterExecution = Instant.now().getEpochSecond(); + + assertThat(timestamp).isBetween(currentTimestamp, afterExecution); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampTest.java new file mode 100644 index 0000000..f5c12c3 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsExtractorValidTimestampTest.java @@ -0,0 +1,67 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class KeywordsExtractorValidTimestampTest { + + private final String keyword; + private final int length; + private KeywordsExtractor keywordsExtractor; + + private static final Collection VALID_TIMESTAMP_KEYWORDS = Arrays.asList(new Object[][]{ + {"#Timestamp", 10}, + {"#Timestamp12", 10 + 2}, + {"1#Timestamp", 1 + 10}, + {"1#Timestamp2", 1 + 10 +1} + }); + + public KeywordsExtractorValidTimestampTest(String keyword, Integer length) { + this.keyword = keyword; + this.length = length; + } + + @Before + public void setUp() { + this.keywordsExtractor = new KeywordsExtractor(); + } + + @Parameterized.Parameters + public static Collection data() { + return VALID_TIMESTAMP_KEYWORDS; + } + + @Test + public void checkValidRandomStringKeyword() { + String substitution = keywordsExtractor.substituteStringKeyword(this.keyword, 1); + assertEquals(substitution.length(), this.length); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsHandlerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsHandlerTest.java new file mode 100644 index 0000000..e67d4a3 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsHandlerTest.java @@ -0,0 +1,304 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.DEFAULT_STRING_LENGTH; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Queue; +import org.junit.jupiter.api.Test; + +class KeywordsHandlerTest { + + private static final String TEMPLATE_JSON = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"#RandomString\"\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"measurementsForVfSclaingFieldsVersion\": 2.0,\n" + + " \"additionalMeasurements\": {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"extraFields\": {\n" + + " \"name\": \"#RandomString(4)\",\n" + + " \"value\": \"1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + private static final String TEMPLATE_JSON_WITH_MANY_KEYWORDS_INSIDE_SINGLE_VALUE = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain1\": \"#RandomString(1) #RandomString(2) #RandomString(3)\",\n" + + " \"domain2\": \"1 #RandomString(1) 2\"\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"measurementsForVfSclaingFieldsVersion\": 2.0,\n" + + " \"additionalMeasurements\": {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"extraFields\": {\n" + + " \"value\": \"1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + private static final String TEMPLATE_JSON_WITH_ARRAY = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"#RandomString(1)\",\n" + + " \"version\": 2.0\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"additionalMeasurements\": [\n" + + " {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"arrayOfFields\": [\n" + + " {\n" + + " \"name\": \"G711AudioPort\",\n" + + " \"value\": \"1\"\n" + + " },\n" + + " {\n" + + " \"name\": [\"1\",\"2\"],\n" + + " \"value\": \"#RandomString(2)\"\n" + + " },\n" + + " {\n" + + " \"name\": \"G722AudioPort\",\n" + + " \"value\": \"1\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " }\n" + + "}"; + + private static final String TEMPLATE_ONE_INCREMENT_JSON = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"#RandomString\"\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"measurementsForVfSclaingFieldsVersion\": 2.0,\n" + + " \"additionalMeasurements\": {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"extraFields\": {\n" + + " \"name\": \"#RandomString(4)\",\n" + + " \"value\": \"#Increment\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + private static final String TEMPLATE_WITH_SIMPLE_VALUE= "\"#RandomString(4)\""; + + private static final String TEMPLATE_WITH_ARRAY_OF_PRIMITIVES = "[ 1, \"#RandomString(5)\", 3]"; + + private static final String TEMPLATE_TWO_INCREMENT_JSON = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"#RandomString\"\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"measurementsForVfSclaingFieldsVersion\": 2.0,\n" + + " \"additionalMeasurements\": {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"extraFields\": {\n" + + " \"name\": \"#RandomString(4)\",\n" + + " \"value\": \"#Increment\",\n" + + " \"otherValue\": \"#Increment\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + private Gson gson = new Gson(); + + @Test + void shouldReplaceRandomStringKeyword() { + // given + JsonObject templateJson = gson.fromJson(TEMPLATE_JSON, JsonObject.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> 1); + + // when + JsonObject resultJson = keywordsHandler.substituteKeywords(templateJson, "").getAsJsonObject(); + + // then + String extraFields = resultJson + .get("event").getAsJsonObject() + .get("measurementsForVfScalingFields").getAsJsonObject() + .get("additionalMeasurements").getAsJsonObject() + .get("extraFields").getAsJsonObject() + .get("name").getAsString(); + String newDomain = resultJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain").getAsString(); + + assertThat(extraFields.length()).isEqualTo(4); + assertThat(newDomain.length()).isEqualTo(DEFAULT_STRING_LENGTH); + } + + @Test + void shouldReplaceRandomStringKeywordsInsideSingleValue() { + // given + JsonObject templateJson = gson.fromJson(TEMPLATE_JSON_WITH_MANY_KEYWORDS_INSIDE_SINGLE_VALUE, JsonObject.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> 1); + + // when + JsonObject resultJson = keywordsHandler.substituteKeywords(templateJson, "").getAsJsonObject(); + + // then + String newDomain1 = resultJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain1").getAsString(); + String newDomain2 = resultJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain2").getAsString(); + + assertThat(newDomain1.length()).isEqualTo(1+1+2+1+3); + assertThat(newDomain2.length()).isEqualTo(1+1+1+1+1); + } + + @Test + void shouldReplaceRandomStringKeywordInTeplateAsArrayWithPrimitves() { + // given + JsonElement templateJson = gson.fromJson(TEMPLATE_WITH_ARRAY_OF_PRIMITIVES, JsonElement.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> 1); + + // when + JsonElement resultJson = keywordsHandler.substituteKeywords(templateJson, ""); + assertThat(resultJson.getAsJsonArray().get(1).getAsString().length()).isEqualTo(5); + } + + @Test + void shouldReplaceRandomStringKeywordInTeplateAsSimpleValue() { + // given + JsonElement templateJson = gson.fromJson(TEMPLATE_WITH_SIMPLE_VALUE, JsonElement.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> 1); + + // when + JsonElement resultJson = keywordsHandler.substituteKeywords(templateJson, ""); + + // then + assertThat(resultJson.getAsString().length()).isEqualTo(4); + } + + @Test + void shouldReplaceRandomStringKeywordInTeplateWithJsonArray() { + // given + JsonElement templateJson = gson.fromJson(TEMPLATE_JSON_WITH_ARRAY, JsonElement.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> 1); + + // when + JsonObject resultJson = keywordsHandler.substituteKeywords(templateJson, "").getAsJsonObject(); + + // then + String actualValue = resultJson + .get("event").getAsJsonObject() + .get("measurementsForVfScalingFields").getAsJsonObject() + .get("additionalMeasurements").getAsJsonArray() + .get(0).getAsJsonObject() + .get("arrayOfFields").getAsJsonArray() + .get(1).getAsJsonObject() + .get("value").getAsString(); + String otherActualValue = resultJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain").getAsString(); + + assertThat(otherActualValue.length()).isEqualTo(1); + assertThat(actualValue.length()).isEqualTo(2); + } + + @Test + void shouldReplaceOneIncrementKeyword() { + // given + final Integer newIncrementedValue = 2; + JsonObject templateJson = gson.fromJson(TEMPLATE_ONE_INCREMENT_JSON, JsonObject.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), (id) -> newIncrementedValue); + + // when + JsonObject resultJson = keywordsHandler.substituteKeywords(templateJson, "some random id").getAsJsonObject(); + + // then + String actualValue = resultJson + .get("event").getAsJsonObject() + .get("measurementsForVfScalingFields").getAsJsonObject() + .get("additionalMeasurements").getAsJsonObject() + .get("extraFields").getAsJsonObject() + .get("value").getAsString(); + + assertThat(actualValue).isEqualTo(newIncrementedValue.toString()); + } + + @Test + void shouldReplaceTwoIncrementKeyword() { + // given + final Integer firstIncrementValue = 2; + final Integer secondIncrementValue = 3; + JsonObject templateJson = gson.fromJson(TEMPLATE_TWO_INCREMENT_JSON, JsonObject.class); + KeywordsHandler keywordsHandler = new KeywordsHandler(new KeywordsExtractor(), new IncrementProvider() { + Queue<Integer> sequenceOfValues = new LinkedList<>( + Arrays.asList(firstIncrementValue, secondIncrementValue)); + + @Override + public int getAndIncrement(String id) { + return sequenceOfValues.poll(); + } + }); + + // when + JsonObject resultJson = keywordsHandler.substituteKeywords(templateJson, "some random id").getAsJsonObject(); + resultJson = keywordsHandler.substituteKeywords(templateJson, "some random id").getAsJsonObject(); + + // then + String actualValue = resultJson + .get("event").getAsJsonObject() + .get("measurementsForVfScalingFields").getAsJsonObject() + .get("additionalMeasurements").getAsJsonObject() + .get("extraFields").getAsJsonObject() + .get("value").getAsString(); + + String actualOtherValue = resultJson + .get("event").getAsJsonObject() + .get("measurementsForVfScalingFields").getAsJsonObject() + .get("additionalMeasurements").getAsJsonObject() + .get("extraFields").getAsJsonObject() + .get("otherValue").getAsString(); + + assertThat(actualValue).isEqualTo(secondIncrementValue.toString()); + assertThat(actualOtherValue).isEqualTo(secondIncrementValue.toString()); + + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsValueProviderTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsValueProviderTest.java new file mode 100644 index 0000000..73e4c31 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/KeywordsValueProviderTest.java @@ -0,0 +1,81 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.onap.pnfsimulator.simulator.KeywordsValueProvider.DEFAULT_STRING_LENGTH; + +import java.util.Random; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; + +class KeywordsValueProviderTest { + + @RepeatedTest(10) + void randomLimitedStringTest() { + String supplierResult = KeywordsValueProvider.getRandomLimitedString().apply(); + assertEquals(supplierResult.length(), DEFAULT_STRING_LENGTH); + } + + @RepeatedTest(10) + void randomStringTest() { + int length = new Random().nextInt(15) + 1; + String supplierResult = KeywordsValueProvider.getRandomString().apply(length); + assertEquals(supplierResult.length(), length); + } + + @RepeatedTest(10) + void randomIntegerTest(){ + int min = new Random().nextInt(10) + 1; + int max = new Random().nextInt(1000) + 20; + String supplierResult = KeywordsValueProvider.getRandomInteger().apply(min, max); + assertTrue(Integer.parseInt(supplierResult)>=min); + assertTrue(Integer.parseInt(supplierResult)<=max); + } + + @Test + void randomIntegerContainsMaximalAndMinimalValuesTest(){ + int anyNumber = new Random().nextInt(10) + 1; + String supplierResult = KeywordsValueProvider.getRandomInteger().apply(anyNumber, anyNumber); + assertEquals(Integer.parseInt(supplierResult), anyNumber); + } + + @Test + void randomIntegerFromNegativeRangeTest(){ + String supplierResult = KeywordsValueProvider.getRandomInteger().apply(-20, -20); + assertEquals(Integer.parseInt(supplierResult), -20); + } + + @RepeatedTest(10) + void randomIntegerFromParametersWithDifferentOrdersTest(){ + String supplierResult = KeywordsValueProvider.getRandomInteger().apply(-20, -10); + assertTrue(Integer.parseInt(supplierResult)>=-20); + assertTrue(Integer.parseInt(supplierResult)<=-10); + } + + @RepeatedTest(10) + void epochSecondGeneratedInCorrectFormatTest(){ + String supplierResult = KeywordsValueProvider.getEpochSecond().apply(); + assertEquals(supplierResult.length(), 10); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java new file mode 100644 index 0000000..0196eb0 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/SimulatorServiceTest.java @@ -0,0 +1,227 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.onap.pnfsimulator.event.EventData; +import org.onap.pnfsimulator.event.EventDataService; +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.utils.ssl.SSLAuthenticationHelper; +import org.onap.pnfsimulator.simulator.scheduler.EventScheduler; +import org.onap.pnfsimulator.simulatorconfig.SimulatorConfig; +import org.onap.pnfsimulator.simulatorconfig.SimulatorConfigService; +import org.quartz.SchedulerException; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.security.GeneralSecurityException; + +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.internal.verification.VerificationModeFactory.times; + +class SimulatorServiceTest { + + private static final String VES_URL = "http://0.0.0.0:8080"; + private static final Gson GSON = new Gson(); + 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" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"notification\",\n" + + " \"eventName\": \"vFirewallBroadcastPackets\"\n" + + " },\n" + + " \"notificationFields\": {\n" + + " \"arrayOfNamedHashMap\": [{\n" + + " \"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" + + " \"commonEventHeader\":{ \n" + + " \"domain\":\"notification\",\n" + + " \"eventName\":\"#RandomString(20)\",\n" + + " \"eventOrderNo\":\"#Increment\"}}}", JsonObject.class); + private static final String SOME_CUSTOM_SOURCE = "SomeCustomSource"; + private static final String CLOSED_LOOP_VNF ="ClosedLoopVNF"; + private static final String SAMPLE_ID = "sampleId"; + private static final EventData SAMPLE_EVENT = EventData.builder().id("1").build(); + private final ArgumentCaptor<JsonObject> bodyCaptor = ArgumentCaptor.forClass(JsonObject.class); + private final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class); + private final ArgumentCaptor<Integer> repeatCountCaptor = ArgumentCaptor + .forClass(Integer.class); + private final ArgumentCaptor<String> templateNameCaptor = ArgumentCaptor.forClass(String.class); + 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 SimulatorService simulatorService; + private EventDataService eventDataService; + private EventScheduler eventScheduler; + private SimulatorConfigService simulatorConfigService; + private static TemplatePatcher templatePatcher = new TemplatePatcher(); + private static TemplateReader templateReader = new FilesystemTemplateReader( + "src/test/resources/org/onap/pnfsimulator/simulator/", GSON); + + @BeforeEach + void setUp() { + eventDataService = mock(EventDataService.class); + eventScheduler = mock(EventScheduler.class); + simulatorConfigService = mock(SimulatorConfigService.class); + + simulatorService = new SimulatorService(templatePatcher, templateReader, + eventScheduler, eventDataService, simulatorConfigService, new SSLAuthenticationHelper()); + } + + @Test + void shouldTriggerEventWithGivenParams() throws IOException, SchedulerException, GeneralSecurityException { + String templateName = "validExampleMeasurementEvent.json"; + SimulatorParams simulatorParams = new SimulatorParams(VES_URL, 1, 1); + SimulatorRequest simulatorRequest = new SimulatorRequest(simulatorParams, + templateName, VALID_PATCH); + + doReturn(SAMPLE_EVENT).when(eventDataService).persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), any(JsonObject.class)); + + simulatorService.triggerEvent(simulatorRequest); + + assertEventHasExpectedStructure(VES_URL, templateName, SOME_CUSTOM_SOURCE); + } + + @Test + void shouldTriggerEventWithDefaultVesUrlWhenNotProvidedInRequest() throws IOException, SchedulerException, GeneralSecurityException { + String templateName = "validExampleMeasurementEvent.json"; + SimulatorRequest simulatorRequest = new SimulatorRequest( + new SimulatorParams("", 1, 1), + templateName, VALID_PATCH); + + URL inDbVesUrl = new URL("http://0.0.0.0:8080/eventListener/v6"); + doReturn(SAMPLE_EVENT).when(eventDataService).persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), any(JsonObject.class)); + when(simulatorConfigService.getConfiguration()).thenReturn(new SimulatorConfig(SAMPLE_ID, inDbVesUrl)); + + simulatorService.triggerEvent(simulatorRequest); + + assertEventHasExpectedStructure(inDbVesUrl.toString(), templateName, SOME_CUSTOM_SOURCE); + } + + @Test + void shouldThrowJsonSyntaxWhenInvalidJson() { + //given + JsonObject patch = GSON.fromJson("{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"sourceName\": \"" + SOME_CUSTOM_SOURCE + "\"\n" + + " }\n" + + " }\n" + + "}\n", JsonObject.class); + EventData eventData = EventData.builder().id("1").build(); + + SimulatorParams simulatorParams = new SimulatorParams(VES_URL, 1, 1); + SimulatorRequest simulatorRequest = new SimulatorRequest(simulatorParams, + "invalidJsonStructureEvent.json", patch); + doReturn(eventData).when(eventDataService).persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), any(JsonObject.class)); + + //when + assertThrows(JsonSyntaxException.class, + () -> simulatorService.triggerEvent(simulatorRequest)); + } + + @Test + void shouldHandleNonExistingPatchSection() throws IOException, SchedulerException, GeneralSecurityException { + String templateName = "validExampleMeasurementEvent.json"; + SimulatorRequest simulatorRequest = new SimulatorRequest( + new SimulatorParams("", 1, 1), + templateName, null); + + URL inDbVesUrl = new URL("http://0.0.0.0:8080/eventListener/v6"); + doReturn(SAMPLE_EVENT).when(eventDataService).persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), any(JsonObject.class)); + doReturn(new SimulatorConfig(SAMPLE_ID, inDbVesUrl)).when(simulatorConfigService).getConfiguration(); + + simulatorService.triggerEvent(simulatorRequest); + + assertEventHasExpectedStructure(inDbVesUrl.toString(), templateName, CLOSED_LOOP_VNF); + } + + @Test + void shouldSuccessfullySendOneTimeEventWithVesUrlWhenPassed() throws IOException, GeneralSecurityException { + SimulatorService spiedTestedService = spy(new SimulatorService(templatePatcher,templateReader, eventScheduler, eventDataService, simulatorConfigService, new SSLAuthenticationHelper())); + + HttpClientAdapter adapterMock = mock(HttpClientAdapter.class); + doNothing().when(adapterMock).send(eventContentCaptor.capture()); + doReturn(adapterMock).when(spiedTestedService).createHttpClientAdapter(any(String.class)); + FullEvent event = new FullEvent(VES_URL, VALID_FULL_EVENT); + + spiedTestedService.triggerOneTimeEvent(event); + + assertThat(eventContentCaptor.getValue()).isEqualTo(VALID_FULL_EVENT.toString()); + verify(eventDataService, times(1)).persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), any(JsonObject.class)); + verify(adapterMock, times(1)).send(VALID_FULL_EVENT.toString()); + } + + @Test + void shouldSubstituteKeywordsAndSuccessfullySendOneTimeEvent() throws IOException, GeneralSecurityException { + SimulatorService spiedTestedService = spy(new SimulatorService(templatePatcher,templateReader, eventScheduler, eventDataService, simulatorConfigService, new SSLAuthenticationHelper())); + + HttpClientAdapter adapterMock = mock(HttpClientAdapter.class); + doNothing().when(adapterMock).send(eventContentCaptor.capture()); + doReturn(adapterMock).when(spiedTestedService).createHttpClientAdapter(any(String.class)); + FullEvent event = new FullEvent(VES_URL, FULL_EVENT_WITH_KEYWORDS); + + spiedTestedService.triggerOneTimeEvent(event); + + JsonObject sentContent = GSON.fromJson(eventContentCaptor.getValue(), JsonElement.class).getAsJsonObject(); + assertThat(sentContent.getAsJsonObject("event").getAsJsonObject("commonEventHeader").get("eventOrderNo").getAsString()).isEqualTo("1"); + assertThat(sentContent.getAsJsonObject("event").getAsJsonObject("commonEventHeader").get("eventName").getAsString()).hasSize(20); + } + + + 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()); + assertThat(vesUrlCaptor.getValue()).isEqualTo(expectedVesUrl); + assertThat(intervalCaptor.getValue()).isEqualTo(1); + assertThat(repeatCountCaptor.getValue()).isEqualTo(1); + assertThat(templateNameCaptor.getValue()).isEqualTo(templateName); + String actualSourceName = GSON.fromJson(bodyCaptor.getValue(), JsonObject.class) + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("sourceName").getAsString(); + assertThat(actualSourceName).isEqualTo(sourceNameString); + verify(eventDataService) + .persistEventData(any(JsonObject.class), any(JsonObject.class), any(JsonObject.class), + any(JsonObject.class)); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplatePatcherTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplatePatcherTest.java new file mode 100644 index 0000000..52e0d6a --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplatePatcherTest.java @@ -0,0 +1,164 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.assertj.core.api.AssertionsForInterfaceTypes; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +class TemplatePatcherTest { + + private static final String TEMPLATE_JSON = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"measurementsForVfScaling\"\n" + + " },\n" + + " \"measurementsForVfScalingFields\": {\n" + + " \"measurementsForVfSclaingFieldsVersion\": 2.0,\n" + + " \"additionalMeasurements\": {\n" + + " \"name\": \"licenseUsage\",\n" + + " \"extraFields\": {\n" + + " \"name\": \"G711AudioPort\",\n" + + " \"value\": \"1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + private TemplatePatcher templatePatcher; + private Gson gson = new Gson(); + private JsonObject templateJson; + + @BeforeEach + void setUp() { + templatePatcher = new TemplatePatcher(); + templateJson = gson.fromJson(TEMPLATE_JSON, JsonObject.class); + } + + @Test + void shouldReplaceJsonElementsInTemplate() { + //given + String patchJsonString = "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"newDomain\"\n" + + " }\n" + + " }\n" + + "}"; + JsonObject patchJson = gson.fromJson(patchJsonString, JsonObject.class); + + //when + JsonObject requestJson = templatePatcher.mergeTemplateWithPatch(templateJson, patchJson); + + //then + String newDomain = requestJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain").getAsString(); + assertThat(newDomain).isEqualTo("newDomain"); + } + + @Test + void shouldAddWholeJsonObjectToTemplateWhenItFinished() { + //given + String patchJsonString = + "{\n" + + " \"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": {\n" + + " \"extraFields\": {\n" + + " \"name\": \"G711AudioPort\",\n" + + " \"value\": \"1\"\n" + + " }\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + JsonObject patchJson = gson.fromJson(patchJsonString, JsonObject.class); + + //when + JsonObject requestJson = templatePatcher.mergeTemplateWithPatch(templateJson, patchJson); + + //then + JsonElement newDomain = requestJson + .get("event").getAsJsonObject() + .get("commonEventHeader").getAsJsonObject() + .get("domain"); + assertThat(newDomain.isJsonObject()).isTrue(); + JsonObject newDomainJO = newDomain.getAsJsonObject(); + AssertionsForInterfaceTypes.assertThat(newDomainJO.keySet()).containsExactly("extraFields"); + JsonObject newDomainExtraFields = newDomainJO.get("extraFields").getAsJsonObject(); + AssertionsForInterfaceTypes.assertThat(newDomainExtraFields.keySet()).containsExactly("name", "value"); + } + + @Test + void shouldReplaceJsonObjectWithJsonElementFromPatch() { + //given + String patchJsonString = "{ \"event\": \"test\" }"; + JsonObject patchJson = gson.fromJson(patchJsonString, JsonObject.class); + + //when + JsonObject requestJson = templatePatcher.mergeTemplateWithPatch(templateJson, patchJson); + + //then + assertThat(requestJson.get("event").isJsonObject()).isFalse(); + assertThat(requestJson.get("event").getAsString()).isEqualTo("test"); + } + + @Test + void shouldAddNewKeyIfPatchHasItAndTempleteDoesnt() { + //given + String patchJsonString = "{ \"newTestKey\": { \"newTestKeyChild\":\"newTestValue\" }}"; + JsonObject patchJson = gson.fromJson(patchJsonString, JsonObject.class); + + //when + JsonObject requestJson = templatePatcher.mergeTemplateWithPatch(templateJson, patchJson); + + //then + assertThat(requestJson.get("event").isJsonObject()).isTrue(); + assertThat(requestJson.get("newTestKey").isJsonObject()).isTrue(); + JsonObject newTestKey = requestJson.get("newTestKey").getAsJsonObject(); + AssertionsForInterfaceTypes.assertThat(newTestKey.keySet()).containsExactly("newTestKeyChild"); + assertThat(newTestKey.get("newTestKeyChild").getAsString()).isEqualTo("newTestValue"); + + } + + + @Test + void shouldNotChangeInputTemplateParam() { + //given + String patchJsonString = "{ \"newTestKey\": { \"newTestKeyChild\":\"newTestValue\" }}"; + JsonObject patchJson = gson.fromJson(patchJsonString, JsonObject.class); + + //when + templatePatcher.mergeTemplateWithPatch(templateJson, patchJson); + + //then + assertThat(templateJson).isEqualTo(gson.fromJson(TEMPLATE_JSON, JsonObject.class)); + + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplateReaderTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplateReaderTest.java new file mode 100644 index 0000000..f029fce --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/TemplateReaderTest.java @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonSyntaxException; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.TestPropertySource; + +import java.io.IOException; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +@TestPropertySource +class TemplateReaderTest { + + private FilesystemTemplateReader templateReader = new FilesystemTemplateReader("src/test/resources/org/onap/pnfsimulator/simulator/", new Gson()); + + @Test + void testShouldReadJsonFromFile() throws IOException { + JsonObject readJson = templateReader.readTemplate("validExampleMeasurementEvent.json"); + assertThat(readJson.keySet()).containsOnly("event"); + assertThat(readJson.get("event").getAsJsonObject().keySet()).containsExactlyInAnyOrder("commonEventHeader", "measurementsForVfScalingFields"); + } + + @Test + void testShouldRaiseExceptionWhenInvalidJsonIsRead() { + Assertions.assertThrows(JsonSyntaxException.class, () -> templateReader.readTemplate("invalidJsonStructureEvent.json")); + } + +} 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 new file mode 100644 index 0000000..63c1b72 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/HttpClientAdapterImplTest.java @@ -0,0 +1,99 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.client.HttpClient; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; + +import static org.assertj.core.api.Assertions.assertThat; +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.mock; +import static org.mockito.Mockito.verify; + +class HttpClientAdapterImplTest { + + private static final String HTTPS_URL = "https://0.0.0.0:8443/"; + private static final String HTTP_URL = "http://0.0.0.0:8000/"; + + private HttpClient httpClient; + private HttpResponse httpResponse; + + @BeforeEach + void setup() { + httpClient = mock(HttpClient.class); + httpResponse = mock(HttpResponse.class); + } + + @Test + void sendShouldSuccessfullySendRequestGivenValidUrl() throws IOException { + assertAdapterSentRequest("http://valid-url:8080"); + } + + @Test + void sendShouldSuccessfullySendRequestGivenValidUrlUsingHTTPS() throws IOException { + assertAdapterSentRequest("https://valid-url:8443"); + } + + @Test + void shouldThrowExceptionWhenMalformedVesUrlPassed(){ + assertThrows(MalformedURLException.class, () -> new HttpClientAdapterImpl("http://blablabla:VES-PORT", new SSLAuthenticationHelper())); + } + @Test + void shouldCreateAdapterWithClientNotSupportingSSLConnection() throws IOException, GeneralSecurityException { + HttpClientAdapter adapterWithHttps = new HttpClientAdapterImpl(HTTPS_URL, new SSLAuthenticationHelper()); + try { + adapterWithHttps.send("sample"); + } catch (Exception actualException) { + assertThat(actualException).hasStackTraceContaining(SSLConnectionSocketFactory.class.toString()); + } + } + + @Test + void shouldCreateAdapterWithClientSupportingPlainConnectionOnly() throws IOException, GeneralSecurityException { + HttpClientAdapter adapterWithHttps = new HttpClientAdapterImpl(HTTP_URL, new SSLAuthenticationHelper()); + try { + adapterWithHttps.send("sample"); + } catch (Exception actualException) { + assertThat(actualException).hasStackTraceContaining(PlainConnectionSocketFactory.class.toString()); + } + } + + private void assertAdapterSentRequest(String targetUrl) throws IOException { + HttpClientAdapter adapter = new HttpClientAdapterImpl(httpClient, targetUrl); + doReturn(httpResponse).when(httpClient).execute(any()); + + adapter.send("test-msg"); + + verify(httpClient).execute(any()); + verify(httpResponse).getStatusLine(); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslSupportLevelTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslSupportLevelTest.java new file mode 100644 index 0000000..ff41c44 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/client/utils/ssl/SslSupportLevelTest.java @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.utils.ssl; + +import org.junit.jupiter.api.Test; + +import java.net.MalformedURLException; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class SslSupportLevelTest { + + private static final String HTTPS_URL = "https://127.0.0.1:8443/"; + private static final String HTTP_URL = "http://127.0.0.1:8080/"; + + @Test + void testShouldReturnAlwaysTrustSupportLevelForHttpsUrl() throws MalformedURLException { + SslSupportLevel actualSupportLevel = SslSupportLevel.getSupportLevelBasedOnProtocol(HTTPS_URL); + assertEquals(actualSupportLevel, SslSupportLevel.ALWAYS_TRUST); + } + + @Test + void testShouldReturnNoneSupportLevelForHttpUrl() throws MalformedURLException { + SslSupportLevel actualSupportLevel = SslSupportLevel.getSupportLevelBasedOnProtocol(HTTP_URL); + assertEquals(actualSupportLevel, SslSupportLevel.NONE); + } + + @Test + void testShouldRaiseExceptionWhenInvalidUrlPassed(){ + assertThrows(MalformedURLException.class, () -> SslSupportLevel.getSupportLevelBasedOnProtocol("http://bla:VES-PORT/")); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventJobTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventJobTest.java new file mode 100644 index 0000000..25ed84c --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventJobTest.java @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.scheduler; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.BODY; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.CLIENT_ADAPTER; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.EVENT_ID; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.KEYWORDS_HANDLER; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.TEMPLATE_NAME; +import static org.onap.pnfsimulator.simulator.scheduler.EventJob.VES_URL; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.onap.pnfsimulator.simulator.KeywordsExtractor; +import org.onap.pnfsimulator.simulator.KeywordsHandler; +import org.onap.pnfsimulator.simulator.client.HttpClientAdapter; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; + +class EventJobTest { + + @Test + void shouldSendEventWhenExecuteCalled() { + //given + EventJob eventJob = new EventJob(); + String templateName = "template name"; + String vesUrl = "http://someurl:80/"; + String eventId = "1"; + JsonParser parser = new JsonParser(); + JsonObject body = parser.parse("{\"a\": \"A\"}").getAsJsonObject(); + HttpClientAdapter clientAdapter = mock(HttpClientAdapter.class); + JobExecutionContext jobExecutionContext = + createMockJobExecutionContext(templateName, eventId, vesUrl, body, clientAdapter); + + ArgumentCaptor<String> vesUrlCaptor = ArgumentCaptor.forClass(String.class); + ArgumentCaptor<String> bodyCaptor = ArgumentCaptor.forClass(String.class); + + //when + eventJob.execute(jobExecutionContext); + + //then + verify(clientAdapter).send(bodyCaptor.capture()); + assertThat(bodyCaptor.getValue()).isEqualTo(body.toString()); + } + + private JobExecutionContext createMockJobExecutionContext(String templateName, String eventId, String vesURL, + JsonObject body, HttpClientAdapter clientAdapter) { + + JobDataMap jobDataMap = new JobDataMap(); + jobDataMap.put(TEMPLATE_NAME, templateName); + jobDataMap.put(KEYWORDS_HANDLER, new KeywordsHandler(new KeywordsExtractor(), (id) -> 1)); + jobDataMap.put(EVENT_ID, eventId); + jobDataMap.put(VES_URL, vesURL); + jobDataMap.put(BODY, body); + jobDataMap.put(CLIENT_ADAPTER, clientAdapter); + + JobExecutionContext jobExecutionContext = mock(JobExecutionContext.class); + JobDetail jobDetail = mock(JobDetail.class); + when(jobExecutionContext.getJobDetail()).thenReturn(jobDetail); + when(jobDetail.getJobDataMap()).thenReturn(jobDataMap); + when(jobDetail.getKey()).thenReturn(new JobKey("jobId", "group")); + return jobExecutionContext; + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventSchedulerTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventSchedulerTest.java new file mode 100644 index 0000000..84df5e9 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulator/scheduler/EventSchedulerTest.java @@ -0,0 +1,149 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.scheduler; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.gson.JsonObject; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.pnfsimulator.simulator.client.utils.ssl.SSLAuthenticationHelper; +import org.quartz.JobDataMap; +import org.quartz.JobDetail; +import org.quartz.JobExecutionContext; +import org.quartz.JobKey; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SimpleTrigger; + +class EventSchedulerTest { + + @InjectMocks + EventScheduler eventScheduler; + + @Mock + Scheduler quartzScheduler; + + @Mock + SSLAuthenticationHelper sslAuthenticationHelper; + + @BeforeEach + void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + void shouldTriggerEventWithGivenConfiguration() throws SchedulerException, IOException, GeneralSecurityException { + //given + ArgumentCaptor<JobDetail> jobDetailCaptor = ArgumentCaptor.forClass(JobDetail.class); + ArgumentCaptor<SimpleTrigger> triggerCaptor = ArgumentCaptor.forClass(SimpleTrigger.class); + + String vesUrl = "http://some:80/"; + int repeatInterval = 1; + int repeatCount = 4; + String testName = "testName"; + String eventId = "1"; + JsonObject body = new JsonObject(); + + //when + eventScheduler.scheduleEvent(vesUrl, repeatInterval, repeatCount, testName, eventId, body); + + //then + verify(quartzScheduler).scheduleJob(jobDetailCaptor.capture(), triggerCaptor.capture()); + JobDataMap actualJobDataMap = jobDetailCaptor.getValue().getJobDataMap(); + assertThat(actualJobDataMap.get(EventJob.BODY)).isEqualTo(body); + assertThat(actualJobDataMap.get(EventJob.TEMPLATE_NAME)).isEqualTo(testName); + assertThat(actualJobDataMap.get(EventJob.VES_URL)).isEqualTo(vesUrl); + + SimpleTrigger actualTrigger = triggerCaptor.getValue(); + // repeat count adds 1 to given value + assertThat(actualTrigger.getRepeatCount()).isEqualTo(repeatCount - 1); + + //getRepeatInterval returns interval in ms + assertThat(actualTrigger.getRepeatInterval()).isEqualTo(repeatInterval * 1000); + } + + @Test + void shouldCancelAllEvents() throws SchedulerException { + //given + List<JobKey> jobsKeys = Arrays.asList(new JobKey("jobName1"), new JobKey("jobName2"), + new JobKey("jobName3"), new JobKey("jobName4")); + List<JobExecutionContext> jobExecutionContexts = createExecutionContextWithKeys(jobsKeys); + when(quartzScheduler.getCurrentlyExecutingJobs()).thenReturn(jobExecutionContexts); + when(quartzScheduler.deleteJobs(jobsKeys)).thenReturn(true); + + //when + boolean isCancelled = eventScheduler.cancelAllEvents(); + + //then + assertThat(isCancelled).isTrue(); + } + + @Test + void shouldCancelSingleEvent() throws SchedulerException { + //given + JobKey jobToRemove = new JobKey("jobName3"); + List<JobKey> jobsKeys = Arrays.asList(new JobKey("jobName1"), new JobKey("jobName2"), + jobToRemove, new JobKey("jobName4")); + List<JobExecutionContext> jobExecutionContexts = createExecutionContextWithKeys(jobsKeys); + + when(quartzScheduler.getCurrentlyExecutingJobs()).thenReturn(jobExecutionContexts); + when(quartzScheduler.deleteJob(jobToRemove)).thenReturn(true); + + //when + boolean isCancelled = eventScheduler.cancelEvent("jobName3"); + + //then + assertThat(isCancelled).isTrue(); + } + + private List<JobExecutionContext> createExecutionContextWithKeys(List<JobKey> jobsKeys) { + List<JobExecutionContext> contexts = new ArrayList<>(); + for (JobKey key : jobsKeys) { + contexts.add(createExecutionContextFromKey(key)); + } + return contexts; + } + + private JobExecutionContext createExecutionContextFromKey(JobKey key) { + JobExecutionContext context = mock(JobExecutionContext.class); + JobDetail jobDetail = mock(JobDetail.class); + when(context.getJobDetail()).thenReturn(jobDetail); + when(jobDetail.getKey()).thenReturn(key); + return context; + } + + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigServiceTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigServiceTest.java new file mode 100644 index 0000000..4ed0972 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/simulatorconfig/SimulatorConfigServiceTest.java @@ -0,0 +1,104 @@ +/* + * ============LICENSE_START======================================================= + * PNF-REGISTRATION-HANDLER + * ================================================================================ + * Copyright (C) 2018 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.simulatorconfig; + +import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.assertj.core.api.Java6Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +class SimulatorConfigServiceTest { + + private static final String SAMPLE_ID = "sampleId"; + private static final String SAMPLE_NEW_VES_URL = "http://localhost:8090/eventListener/v7"; + @Mock + private SimulatorConfigRepository repository; + + @InjectMocks + private SimulatorConfigService service; + + @BeforeEach + void resetMocks() { + initMocks(this); + } + + @Test + void testShouldReturnConfiguration() throws MalformedURLException { + List<SimulatorConfig> expectedConfig = getExpectedConfig(); + when(repository.findAll()).thenReturn(expectedConfig); + + SimulatorConfig configs = service.getConfiguration(); + + assertThat(configs).isNotNull(); + } + + @Test + void testShouldRaiseExceptionWhenNoConfigurationPresent() { + when(repository.findAll()).thenReturn(Lists.emptyList()); + + assertThatThrownBy(() -> service.getConfiguration()) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("No configuration found in db"); + } + + @Test + void testShouldUpdateConfigurationWithVesUrl() throws MalformedURLException { + URL updatedUrl = new URL("http://localhost:8090/listener/v8"); + SimulatorConfig configWithUpdates = new SimulatorConfig("sampleId", updatedUrl); + List<SimulatorConfig> expectedConfig = getExpectedConfig(); + + when(repository.findAll()).thenReturn(expectedConfig); + when(repository.save(any(SimulatorConfig.class))).thenReturn(configWithUpdates); + + SimulatorConfig updatedConfig = service.updateConfiguration(configWithUpdates); + + assertThat(updatedConfig).isEqualToComparingFieldByField(configWithUpdates); + } + + @Test + void testShouldRaiseExceptionWhenNoConfigInDbPresentOnUpdate() throws MalformedURLException { + when(repository.findAll()).thenReturn(Lists.emptyList()); + + SimulatorConfig configWithUpdates = new SimulatorConfig(SAMPLE_ID, new URL(SAMPLE_NEW_VES_URL)); + + assertThatThrownBy(() -> service.updateConfiguration(configWithUpdates)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("No configuration found in db"); + } + + private List<SimulatorConfig> getExpectedConfig() throws MalformedURLException { + URL sampleVesUrl = new URL("http://localhost:8080/eventListener/v7"); + SimulatorConfig config = new SimulatorConfig(SAMPLE_ID, sampleVesUrl); + return Lists.newArrayList(config); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/TemplateServiceTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/TemplateServiceTest.java new file mode 100644 index 0000000..0746960 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/TemplateServiceTest.java @@ -0,0 +1,152 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.assertj.core.util.Lists; +import org.bson.Document; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock;; +import org.onap.pnfsimulator.template.search.viewmodel.FlatTemplateContent; +import org.onap.pnfsimulator.template.search.TemplateSearchHelper; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.Query; + +import java.time.Instant; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyObject; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +class TemplateServiceTest { + private static final Gson GSON = new Gson(); + private static final Template SAMPLE_TEMPLATE = new Template("sample name", new Document(), Instant.now().getNano()); + private static final List<Template> SAMPLE_TEMPLATE_LIST = Collections.singletonList(SAMPLE_TEMPLATE); + + @Mock + private TemplateRepository templateRepositoryMock; + + @Mock + private MongoTemplate mongoTemplate; + + @InjectMocks + private TemplateService service; + + @BeforeEach + void setUp() { + initMocks(this); + TemplateSearchHelper searchHelper = new TemplateSearchHelper(mongoTemplate); + service = new TemplateService(templateRepositoryMock, searchHelper); + } + + @Test + void testShouldReturnAllTemplates() { + when(templateRepositoryMock.findAll()).thenReturn(SAMPLE_TEMPLATE_LIST); + + List<Template> actual = service.getAll(); + assertThat(actual).containsExactly(SAMPLE_TEMPLATE_LIST.get(0)); + } + + + @Test + void testShouldGetTemplateBySpecifiedName() { + when(templateRepositoryMock.findById("sample name")).thenReturn(Optional.of(SAMPLE_TEMPLATE)); + + Optional<Template> actualTemplate = service.get("sample name"); + assertThat(actualTemplate).isPresent(); + assertThat(actualTemplate.get()).isEqualTo(SAMPLE_TEMPLATE); + } + + @Test + void testShouldSaveTemplate() { + service.persist(SAMPLE_TEMPLATE); + + verify(templateRepositoryMock, times(1)).save(SAMPLE_TEMPLATE); + } + + @Test + void testShouldDeleteTemplateByName() { + service.delete("sample name"); + + verify(templateRepositoryMock, times(1)).deleteById("sample name"); + } + + + @Test + void testShouldReturnTemplatesAccordingToGivenSearchCriteria() { + doReturn(Lists.emptyList()).when(mongoTemplate).find(any(Query.class), anyObject(), any(String.class)); + + List<String> idsByContentCriteria = service.getIdsByContentCriteria(GSON.fromJson("{\"domain\": \"notification.json\"}", JsonObject.class)); + + assertThat(idsByContentCriteria).isEmpty(); + } + + @Test + void shouldReturnNamesForGivenComposedSearchCriteria(){ + JsonObject composedCriteriaObject = GSON.fromJson("{\"eventName\": \"pnfRegistration_Nokia_5gDu\", \"sequence\": 1}", JsonObject.class); + List<FlatTemplateContent> arr = Lists.newArrayList(new FlatTemplateContent("sampleId", null)); + + doReturn(arr).when(mongoTemplate).find(any(Query.class), anyObject(), any(String.class)); + + List<String> idsByContentCriteria = service.getIdsByContentCriteria(composedCriteriaObject); + assertThat(idsByContentCriteria).containsOnly("sampleId"); + } + + @Test + void shouldReturnFalseWhenOverwritingWithoutForce() { + String id = "someTemplate"; + Template template = new Template(id, new Document(), Instant.now().getNano()); + when(templateRepositoryMock.existsById(id)).thenReturn(true); + boolean actual = service.tryPersistOrOverwrite(template, false); + Assert.assertFalse(actual); + } + + @Test + void shouldReturnTrueWhenOverwritingWithForce() { + String id = "someTemplate"; + Template template = new Template(id, new Document(), Instant.now().getNano()); + when(templateRepositoryMock.existsById(id)).thenReturn(true); + boolean actual = service.tryPersistOrOverwrite(template, true); + Assert.assertTrue(actual); + } + + @Test + void shouldReturnTrueWhenSavingNonExistingTemplate() { + String id = "someTemplate"; + Template template = new Template(id, new Document(), Instant.now().getNano()); + when(templateRepositoryMock.existsById(id)).thenReturn(false); + boolean actual = service.tryPersistOrOverwrite(template, false); + Assert.assertTrue(actual); + } + +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/JsonUtilsTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/JsonUtilsTest.java new file mode 100644 index 0000000..fa0bed1 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/JsonUtilsTest.java @@ -0,0 +1,166 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +class JsonUtilsTest { + + private static final Gson GSON_HELPER = new Gson(); + private JsonUtils utils; + + @BeforeEach + void setUp() { + utils = new JsonUtils(); + } + + private static final String NOTIFICATION_JSON = "{\n\"event\": {\n" + + " \"commonEventHeader\": {\n" + + " \"domain\": \"notification\",\n" + + " \"eventName\": \"vFirewallBroadcastPackets\"\n" + + " },\n" + + " \"notificationFields\": {\n" + + " \"changeIdentifier\": \"PM_MEAS_FILES\",\n" + + " \"arrayOfNamedHashMap\": [{\n" + + " \"name\": \"A20161221.1031-1041.bin.gz\",\n" + + " \"hashMap\": {\n" + + " \"fileformatType\": \"org.3GPP.32.435#measCollec\",\n" + + " \"fileFormatVersion\": \"V10\"\n"+ + " }\n" + + " }, {\n" + + " \"name\": \"A20161222.1042-1102.bin.gz\",\n" + + " \"hashMap\": {\n" + + " \"fileFormatType\": \"org.3GPP.32.435#measCollec\",\n" + + " \"fileFormatVersion\": \"1.0.0\"\n" + + " }\n" + + " }],\n" + + " \"notificationFieldsVersion\": \"2.0\"\n}\n\n}}"; + private static final String EXPECTED_FLATTENED_NOTIFICATION = "{" + + " \":event:commonEventHeader:domain\" : \"notification\"," + + " \":event:commonEventHeader:eventName\" : \"vFirewallBroadcastPackets\"," + + " \":event:notificationFields:changeIdentifier\" : \"PM_MEAS_FILES\"," + + " \":event:notificationFields:arrayOfNamedHashMap[0]:name\" : \"A20161221.1031-1041.bin.gz\"," + + " \":event:notificationFields:arrayOfNamedHashMap[0]:hashMap:fileformatType\" : \"org.3GPP.32.435#measCollec\"," + + " \":event:notificationFields:arrayOfNamedHashMap[0]:hashMap:fileFormatVersion\" : \"V10\"," + + " \":event:notificationFields:arrayOfNamedHashMap[1]:name\" : \"A20161222.1042-1102.bin.gz\"," + + " \":event:notificationFields:arrayOfNamedHashMap[1]:hashMap:fileFormatType\" : \"org.3GPP.32.435#measCollec\"," + + " \":event:notificationFields:arrayOfNamedHashMap[1]:hashMap:fileFormatVersion\" : \"1.0.0\"," + + " \":event:notificationFields:notificationFieldsVersion\" : \"2.0\" }"; + + @Test + void shouldFlattenNestedJsonAndSeparateKeysWithDoubleHash(){ + JsonObject templateJson = GSON_HELPER.fromJson(NOTIFICATION_JSON, JsonObject.class); + + JsonObject result = utils.flatten(templateJson); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(EXPECTED_FLATTENED_NOTIFICATION, JsonObject.class)); + } + + @Test + void shouldWorkOnEmptyJsonObject(){ + JsonObject result = utils.flatten(new JsonObject()); + + assertThat(result.toString()).isEqualTo("{}"); + } + + @Test + void shouldFlattenObjectWithArrayValue(){ + String expectedFlattenedObjectWithArray = "{" + + " \":sample[0]\": 1," + + " \":sample[1]\": 2," + + " \":sample[2]\": 3}"; + JsonObject jsonWithPrimitivesArray = GSON_HELPER.fromJson("{\"sample\": [1, 2, 3]}", JsonObject.class); + + JsonObject result = utils.flatten(jsonWithPrimitivesArray); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(expectedFlattenedObjectWithArray, JsonObject.class)); + } + + @Test + void shouldFlattenObjectWithEmptyArrayValue(){ + String expectedFlattenedObjectWithEmptyArray = "{\":sample\": []}"; + JsonObject jsonWithEmptyArrayValue = GSON_HELPER.fromJson("{\"sample\": []}", JsonObject.class); + + JsonObject result = utils.flatten(jsonWithEmptyArrayValue); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(expectedFlattenedObjectWithEmptyArray, JsonObject.class)); + } + + @Test + void shouldFlattenNestedObjectWithEmptyObjectValue(){ + String expectedFlattenedNestedObjectWithEmptyObject = "{\":sample:key\": {}}"; + JsonObject nestedJsonWithEmptyObject = GSON_HELPER.fromJson("{\"sample\": {\"key\":{}}}", JsonObject.class); + + JsonObject result = utils.flatten(nestedJsonWithEmptyObject); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(expectedFlattenedNestedObjectWithEmptyObject, JsonObject.class)); + } + + @Test + void shouldFlattenObjectWithDifferentDataTypes(){ + String jsonWithDifferentDataTypes = "{ \"topLevelKey\": {\"sampleInt\": 1, \"sampleBool\": false, \"sampleDouble\": 10.0, \"sampleString\": \"str\"}}"; + String expectedResult = "{\":topLevelKey:sampleInt\": 1," + + " \":topLevelKey:sampleBool\": \"false\"," + + " \":topLevelKey:sampleDouble\": 10.0," + + " \":topLevelKey:sampleString\": \"str\"}"; + JsonObject templateJson = GSON_HELPER.fromJson(jsonWithDifferentDataTypes, JsonObject.class); + + JsonObject result = utils.flatten(templateJson); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(expectedResult, JsonObject.class)); + } + + @Test + void shouldHandleNullValues(){ + String jsonWithNullValue = "{ \"topLevelKey\": {\"sampleNull\": null, \"sampleString\": \"str\"}}"; + String expectedResult = "{\":topLevelKey:sampleNull\": null," + + " \":topLevelKey:sampleString\": \"str\"}"; + JsonObject templateJson = GSON_HELPER.fromJson(jsonWithNullValue, JsonObject.class); + + JsonObject result = utils.flatten(templateJson); + + assertThat(result).isEqualTo(GSON_HELPER.fromJson(expectedResult, JsonObject.class)); + } + + @Test + void shouldFlattenBsonDocument(){ + Document documentInput = Document.parse(NOTIFICATION_JSON); + + Document result = utils.flatten(documentInput); + + assertThat(result.toJson()).isEqualTo(EXPECTED_FLATTENED_NOTIFICATION); + } + + @Test + void shouldNotChangeEmptyBsonDocument(){ + Document input = Document.parse("{}"); + + Document result = utils.flatten(input); + + assertThat(result.toJson()).isEqualTo("{ }"); + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/TemplateSearchHelperTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/TemplateSearchHelperTest.java new file mode 100644 index 0000000..aeef870 --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/TemplateSearchHelperTest.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.mongodb.BasicDBList; +import org.assertj.core.util.Lists; +import org.bson.Document; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.onap.pnfsimulator.template.search.viewmodel.FlatTemplateContent; +import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.query.BasicQuery; +import org.springframework.data.mongodb.core.query.Query; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyObject; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + + +class TemplateSearchHelperTest { + + private static final Gson GSON = new Gson(); + private static final String FLATTENED_TEMPLATES_VIEW = "flatTemplatesView"; + + @Mock + private MongoTemplate mongoTemplate; + + @InjectMocks + private TemplateSearchHelper helper; + + private static final ArgumentCaptor<Query> QUERY_CAPTOR = ArgumentCaptor.forClass(Query.class); + private static final ArgumentCaptor<String> COLLECTION_NAME_CAPTOR = ArgumentCaptor.forClass(String.class); + private static final ArgumentCaptor<Class<FlatTemplateContent>> CLASS_TYPE_CAPTOR = ArgumentCaptor.forClass((Class) FlatTemplateContent.class); + + + @BeforeEach + void setUp() { + initMocks(this); + } + + @Test + void shouldReturnNamesForGivenComposedSearchCriteria(){ + String expectedComposedQueryString = "{\"$and\":[{\"keyValues\":{\"$elemMatch\":{\"k\":{\"$regex\":\":eventName(?:(\\\\[[\\\\d]+\\\\]))?$\",\"$options\":\"iu\"},\"v\":{\"$regex\":\"^\\\\QpnfRegistration_Nokia_5gDu\\\\E$\",\"$options\":\"iu\"}}}},{\"keyValues\":{\"$elemMatch\":{\"k\":{\"$regex\":\":sequence(?:(\\\\[[\\\\d]+\\\\]))?$\",\"$options\":\"iu\"},\"v\":1.0}}}]}"; + Query expectedQuery = new BasicQuery(expectedComposedQueryString); + + String composedCriteriaInputJson = "{\"eventName\": \"pnfRegistration_Nokia_5gDu\", \"sequence\": 1}"; + JsonObject composedCriteriaObject = GSON.fromJson(composedCriteriaInputJson, JsonObject.class); + + when(mongoTemplate.find(any(Query.class), anyObject(), any(String.class))).thenReturn(Lists.newArrayList(new FlatTemplateContent("sampleId1", null), new FlatTemplateContent("sampleId2", null))); + + List<String> idsOfDocumentMatchingCriteria = helper.getIdsOfDocumentMatchingCriteria(composedCriteriaObject); + + assertThat(idsOfDocumentMatchingCriteria).containsOnly("sampleId1", "sampleId2"); + verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture()); + assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQuery.toString()); + assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW); + assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class); + } + + @Test + void shouldReturnTemplatesAccordingToGivenSearchCriteria() { + Query expectedQueryStructure = new BasicQuery("{\"$and\":[{\"keyValues\": { \"$elemMatch\" : { \"k\" : { \"$regex\" : \":domain(?:(\\\\[[\\\\d]+\\\\]))?$\", \"$options\" : \"iu\" }, \"v\" : { \"$regex\" : \"^\\\\Qnotification\\\\E$\", \"$options\" : \"iu\" }}}}]}"); + + helper.getIdsOfDocumentMatchingCriteria(GSON.fromJson("{\"domain\": \"notification\"}", JsonObject.class)); + + + verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture()); + + assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQueryStructure.toString()); + assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW); + assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class); + } + + @Test + void shouldGetQueryForEmptyJson(){ + JsonObject jsonObject = GSON.fromJson("{}", JsonObject.class); + + String expectedComposedQueryString = "{}"; + Query expectedQuery = new BasicQuery(expectedComposedQueryString); + + helper.getIdsOfDocumentMatchingCriteria(jsonObject); + + verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture()); + Query queryBasedOnCriteria = QUERY_CAPTOR.getValue(); + + assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQuery.toString()); + assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW); + assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class); + } + + + @Test + void shouldGetQueryWithAllTypeValues(){ + JsonObject jsonObject = GSON.fromJson("{\"stringKey\": \"stringValue\", \"numberKey\": 16.00, \"boolKey\": false}", JsonObject.class); + + helper.getIdsOfDocumentMatchingCriteria(jsonObject); + + verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture()); + Query queryBasedOnCriteria = QUERY_CAPTOR.getValue(); + + assertThat(queryBasedOnCriteria.getQueryObject().get("$and")).isInstanceOf(List.class); + List<Document> conditionDocuments = new ArrayList<>((List<Document>) queryBasedOnCriteria.getQueryObject().get("$and")); + List<Document> conditions = conditionDocuments.stream().map(el -> (Document) el.get("keyValues")).map(el -> (Document) el.get("$elemMatch")).collect(Collectors.toList()); + + assertThat(conditionDocuments).hasSize(3); + assertJsonPreparedKeyHasCorrectStructure(conditions.get(0), "stringKey"); + assertThat(conditions.get(0).get("v").toString()).isEqualTo(TemplateSearchHelper.getCaseInsensitive("^\\QstringValue\\E$").toString()); + + assertJsonPreparedKeyHasCorrectStructure(conditions.get(1), "numberKey"); + assertThat(conditions.get(1).get("v")).isEqualTo(16.0); + + assertJsonPreparedKeyHasCorrectStructure(conditions.get(2), "boolKey"); + assertThat(conditions.get(2).get("v")).isEqualTo("false"); + } + + @Test + void shouldThrowExceptionWhenNullIsPresentAsCriteriaValue(){ + JsonObject jsonObject = GSON.fromJson("{\"stringKey\": \"stringValue\", \"nullKey\": null}", JsonObject.class); + + assertThrows(IllegalJsonValueException.class, () -> helper.getIdsOfDocumentMatchingCriteria(jsonObject)); + } + + private void assertJsonPreparedKeyHasCorrectStructure(Document actual, String expectedPattern){ + assertThat(actual.get("k").toString()).isEqualTo(Pattern.compile(String.format(":%s(?:(\\[[\\d]+\\]))?$", expectedPattern)).toString()); + + } +} diff --git a/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilderTest.java b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilderTest.java new file mode 100644 index 0000000..31bcf1c --- /dev/null +++ b/pnfsimulator/src/test/java/org/onap/pnfsimulator/template/search/handler/PrimitiveValueCriteriaBuilderTest.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * Simulator + * ================================================================================ + * Copyright (C) 2019 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.template.search.handler; + +import com.google.gson.JsonPrimitive; +import org.junit.jupiter.api.Test; +import org.springframework.data.mongodb.core.query.Criteria; + +import static org.assertj.core.api.Java6Assertions.assertThat; + +class PrimitiveValueCriteriaBuilderTest { + + private PrimitiveValueCriteriaBuilder builder = new PrimitiveValueCriteriaBuilder(); + + @Test + void testShouldAddRegexLikeCriteriaForStringType(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive("sample")); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : { \"$regex\" : \"^\\\\Qsample\\\\E$\", \"$options\" : \"iu\" } }"); + } + + @Test + void testShouldAddRegexLikeAndEscapeStringWithMetaChars(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive("[1,2,3,4,5]")); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : { \"$regex\" : \"^\\\\Q[1,2,3,4,5]\\\\E$\", \"$options\" : \"iu\" } }"); + } + + @Test + void testShouldAddRegexLikeCriteriaForIntType(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive(1)); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : 1.0 }"); + } + + @Test + void testShouldAddRegexLikeCriteriaForLongType(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive(Long.MAX_VALUE)); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : 9.223372036854776E18 }"); + } + + @Test + void testShouldAddRegexLikeCriteriaForDoubleType(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive(2.5)); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : 2.5 }"); + } + + @Test + void testShouldAddRegexLikeCriteriaForBooleanType(){ + Criteria criteria = builder.applyValueCriteriaBasedOnPrimitiveType(Criteria.where("k").is("10").and("v"), new JsonPrimitive(true)); + + assertThat(criteria.getCriteriaObject().toJson()).isEqualTo("{ \"k\" : \"10\", \"v\" : \"true\" }"); + } + +} diff --git a/pnfsimulator/src/test/resources/application.properties b/pnfsimulator/src/test/resources/application.properties new file mode 100644 index 0000000..6815680 --- /dev/null +++ b/pnfsimulator/src/test/resources/application.properties @@ -0,0 +1,2 @@ +templates.dir=src/test/resources/org/onap/pnfsimulator/simulator +ssl.clientCertificateEnabled=false diff --git a/pnfsimulator/src/test/resources/client.p12 b/pnfsimulator/src/test/resources/client.p12 Binary files differnew file mode 100644 index 0000000..0bbec38 --- /dev/null +++ b/pnfsimulator/src/test/resources/client.p12 diff --git a/pnfsimulator/src/test/resources/logback-test.xml b/pnfsimulator/src/test/resources/logback-test.xml new file mode 100644 index 0000000..ad4f0c8 --- /dev/null +++ b/pnfsimulator/src/test/resources/logback-test.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START======================================================= + Simulator + ================================================================================ + Copyright (C) 2019 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========================================================= + --> + +<Configuration complete="true" compact="true"> + + <Property name="outputFilename" value="pnfsimulator_output"/> + <Property name="log-path" value="${java.io.tmpdir}"/> + <property name="maxFileSize" value="50MB"/> + <property name="maxHistory" value="30"/> + <property name="totalSizeCap" value="10GB"/> + + <appender name="Console" target="SYSTEM_OUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <Pattern>%nopexception%logger + |%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} + |%level + |%replace(%replace(%message){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%rootException){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%marker){'\t','\\\\t'}){'\n','\\\\n'} + |%thread + |%n</Pattern> + </encoder> + </appender> + + <appender name="ROLLING-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> + <encoder> + <pattern>%nopexception%logger + |%date{yyyy-MM-dd'T'HH:mm:ss.SSSXXX,UTC} + |%level + |%replace(%replace(%message){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%mdc){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%rootException){'\t','\\\\t'}){'\n','\\\\n'} + |%replace(%replace(%marker){'\t','\\\\t'}){'\n','\\\\n'} + |%thread + |%n</pattern> + </encoder> + <File>${log-path}/${outputFilename}.log</File> + <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> + <FileNamePattern>${log-path}/${outputFilename}.%d{yyyy-MM-dd}.%i.log.zip</FileNamePattern> + <MaxFileSize>${maxFileSize}</MaxFileSize> + <MaxHistory>${maxHistory}</MaxHistory> + <TotalSizeCap>${totalSizeCap}</TotalSizeCap> + </rollingPolicy> + </appender> + + <root level="info"> + <appender-ref ref="Console" /> + <appender-ref ref="ROLLING-FILE" /> + </root> +</Configuration> diff --git a/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/filesystem/test1.json b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/filesystem/test1.json new file mode 100644 index 0000000..89e4a76 --- /dev/null +++ b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/filesystem/test1.json @@ -0,0 +1,12 @@ +{ + "field1": "value1", + "field2": 2, + "nested": { + "key1": [ + 1, + 2, + 3 + ], + "key2": "sampleValue2" + } +} diff --git a/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/invalidJsonStructureEvent.json b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/invalidJsonStructureEvent.json new file mode 100644 index 0000000..4d6ef7d --- /dev/null +++ b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/invalidJsonStructureEvent.json @@ -0,0 +1 @@ +{"sampleKey1": [{"sampleKey2": "1"}, {"sampleKey2": "2"}] diff --git a/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/validExampleMeasurementEvent.json b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/validExampleMeasurementEvent.json new file mode 100644 index 0000000..989d6ea --- /dev/null +++ b/pnfsimulator/src/test/resources/org/onap/pnfsimulator/simulator/validExampleMeasurementEvent.json @@ -0,0 +1,89 @@ +{ + "event": { + "commonEventHeader": { + "domain": "measurementsForVfScaling", + "eventName": "vFirewallBroadcastPackets", + "eventId": "4cfc-91cf-31a46", + "nfType": "mrfx", + "priority": "Normal", + "reportingEntityName": "myVNF", + "sequence": 1, + "sourceName": "ClosedLoopVNF", + "startEpochMicrosec": 1531616794, + "lastEpochMicrosec": 1531719042, + "version": 2.0 + }, + "measurementsForVfScalingFields": { + "measurementsForVfSclaingFieldsVersion": 2.0, + "measurementsForVfScalingVersion": 2.0, + "measurementInterval": 180, + "concurrentSessions": 2, + "cpuUsageArray": [ + { + "cpuIdentifier": "INTEL_CORE_I7_1", + "percentUsage": 50 + }, + { + "cpuIdentifier": "INTEL_CORE_I7_2", + "percentUsage": 70 + } + ], + "memoryUsageArray": [ + { + "vmIdentifier": "vmIdentifier", + "memoryFree": 50, + "memoryUsed": 10 + } + ], + "vNicUsageArray": [ + { + "receivedTotalPacketsDelta": 30 + } + ], + "numberOfMediaPortsInUse": 100, + "additionalMeasurements": [ + { + "name": "licenseUsage", + "arrayOfFields": [ + { + "name": "G711AudioPort", + "value": "1" + }, + { + "name": "G729AudioPort", + "value": "1" + }, + { + "name": "G722AudioPort", + "value": "1" + }, + { + "name": "AMRAudioPort", + "value": "4" + }, + { + "name": "AMRWBAudioPort", + "value": "5" + }, + { + "name": "OpusAudioPort", + "value": "6" + }, + { + "name": "H263VideoPort", + "value": "7" + }, + { + "name": "H264NonHCVideoPort", + "value": "8" + }, + { + "name": "H264HCVideoPort", + "value": "9" + } + ] + } + ] + } + } +} diff --git a/pnfsimulator/src/test/resources/trustStore b/pnfsimulator/src/test/resources/trustStore Binary files differnew file mode 100644 index 0000000..e90b710 --- /dev/null +++ b/pnfsimulator/src/test/resources/trustStore |