diff --git a/mod2/catalog-service/Dockerfile b/mod2/catalog-service/Dockerfile new file mode 100644 index 0000000..0870a21 --- /dev/null +++ b/ mod2/catalog-service/Dockerfile@@ -0,0 +1,14 @@ +FROM onap/integration-java11:7.1.0 + +ARG PROJECT_BUILD_DIR_NAME +ARG FINAL_JAR + +WORKDIR /usr/app +VOLUME /tmp + +COPY ${PROJECT_BUILD_DIR_NAME}/${FINAL_JAR} . + +EXPOSE 8080 +ENTRYPOINT ["java", \ + "-Djava.security.egd=file:/dev/./urandom", \ + "-jar", "mod-catalog-service.jar"] diff --git a/mod2/catalog-service/lombok.config b/mod2/catalog-service/lombok.config new file mode 100644 index 0000000..8f7e8aa --- /dev/null +++ b/ mod2/catalog-service/lombok.config@@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true
\ No newline at end of file diff --git a/mod2/catalog-service/pom.xml b/mod2/catalog-service/pom.xml new file mode 100644 index 0000000..78cced4 --- /dev/null +++ b/ mod2/catalog-service/pom.xml@@ -0,0 +1,200 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ ============LICENSE_START======================================================= + ~ org.onap.dcae + ~ ================================================================================ + ~ Copyright (c) 2020 AT&T Intellectual Property. 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========================================================= + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onap.oparent</groupId> + <artifactId>oparent</artifactId> + <version>2.0.0</version> + </parent> + <groupId>org.onap.dcaegen2.platform.mod</groupId> + <artifactId>catalog-service</artifactId> + <version>1.0.0-SNAPSHOT</version> + + <properties> + <java.version>11</java.version> + <maven.compiler.source>${java.version}</maven.compiler.source> + <maven.compiler.target>${java.version}</maven.compiler.target> + <spring-boot.version>2.2.5.RELEASE</spring-boot.version> + <dockerfile-maven-plugin.version>1.4.1</dockerfile-maven-plugin.version> + </properties> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.6</version> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-webflux</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>io.projectreactor</groupId> + <artifactId>reactor-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>2.9.2</version> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>2.9.2</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.10</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>4.0.1</version> + </dependency> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>mockwebserver</artifactId> + <version>4.0.1</version> + <scope>test</scope> + </dependency> + </dependencies> + + <dependencyManagement> + <dependencies> + <dependency> + <!-- Import dependency management from Spring Boot --> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>2.2.5.RELEASE</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${spring-boot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.spotify</groupId> + <artifactId>dockerfile-maven-plugin</artifactId> + <version>${dockerfile-maven-plugin.version}</version> + <configuration> + <contextDirectory>${project.basedir}</contextDirectory> + <repository>onap/${project.groupId}.${project.artifactId}</repository> + <buildArgs> + <PROJECT_BUILD_DIR_NAME>target</PROJECT_BUILD_DIR_NAME> + <FINAL_JAR>${project.build.finalName}.jar</FINAL_JAR> + </buildArgs> + </configuration> + <executions> + <execution> + <id>build-image</id> + <phase>package</phase> + <goals> + <goal>build</goal> + </goals> + </execution> + <execution> + <id>tag-and-push-image-latest</id> + <phase>package</phase> + <goals> + <goal>tag</goal> + <goal>push</goal> + </goals> + <configuration> + <repository>onap/${project.groupId}.${project.artifactId}</repository> + <tag>latest</tag> + <useMavenSettingsForAuth>true</useMavenSettingsForAuth> + </configuration> + </execution> + <execution> + <id>tag-and-push-image-with-version</id> + <phase>package</phase> + <goals> + <goal>tag</goal> + <goal>push</goal> + </goals> + <configuration> + <repository>onap/${project.groupId}.${project.artifactId}</repository> + <tag>${project.version}</tag> + <useMavenSettingsForAuth>true</useMavenSettingsForAuth> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <version>2.22.2</version> + </plugin> + </plugins> + <finalName>mod-catalog-service</finalName> + </build> + <reporting> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>cobertura-maven-plugin</artifactId> + <version>2.7</version> + </plugin> + </plugins> + </reporting> +</project>
\ No newline at end of file @@ -0,0 +1,68 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; + +/** + * The application class + */ +@SpringBootApplication +@EnableSwagger2 +public class ModCatalogApplication { + + public static void main(String[] args) { + SpringApplication.run(ModCatalogApplication.class, args); + } + + @Bean + public Docket swaggerConfiguration(){ + // return a prepared Docket instance + return new Docket(DocumentationType.SWAGGER_2) + .select() + //.paths(PathSelectors.ant("/api/*")) + .apis(RequestHandlerSelectors.basePackage("org.onap.dcaegen2.platform.mod")) + .build() + .apiInfo(apiDetails()); + } + + private ApiInfo apiDetails() { + Contact DEFAULT_CONTACT = new Contact("", "", ""); + return new ApiInfo( + "MOD APIs", + "APIs for MOD", + "1.0.0" + ,"", DEFAULT_CONTACT, "", "", new ArrayList<>() + ); + } + //http://localhost:8080/swagger-ui.html for web page view + //http://localhost:8080/v2/api-docs for json view +} @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mock; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactGeneratorStrategy; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * Mock implementation for DeploymentArtifactGenerator + */ +@Component +public class MockDeploymentArtifactGenerator implements DeploymentArtifactGeneratorStrategy { + + /** + * null implementation. + * @param activeSpec + * @param release + * @return + */ + @Override + public Map<String, Object> generateForRelease(Specification activeSpec, String release) { + return null; + } +} @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mock; + +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationValidationStratergy; +import org.springframework.stereotype.Component; + +/** + * Mock implementation for SpecificationValidationStrategy + */ +@Component +public class MockSpecificationValidationStratergy implements SpecificationValidationStratergy { + + /** + * Mock implementation + * @param specificationRequest + * @param release + */ + @Override + public void validate(SpecificationRequest specificationRequest, String release) { + //do nothing + } +} @@ -0,0 +1,65 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.common.AuditFields; +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * A model class which represents Base-Microservice entity + */ +@Data +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +//TODO: migrate the document to microservices +@Document("base-microservices") +public class BaseMicroservice { + private String id; + + @ApiModelProperty(required = true) + private String name; + + @ApiModelProperty(required = true) + private String tag; + + private String serviceName; + + private BaseMsType type; + + private BaseMsLocation location; + + private String namespace; + + private BaseMsStatus status; + + private AuditFields metadata; + + private List<Map<String, String>> msInstances = new ArrayList<>(); +} + @@ -0,0 +1,29 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.basemicroservice; +/** + * Supported values for Base-Microservice location + */ +public enum BaseMsLocation { + CENTRAL, + EDGE, + UNSPECIFIED +} @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.basemicroservice; + +/** + * Supported statuses for Base-Microservice entity + */ +public enum BaseMsStatus { + ACTIVE, RETIRED +} @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.basemicroservice; + +/** + * Supported Types for Base-Microservice + */ +public enum BaseMsType { + TICK, + FM_COLLECTOR, + PM_COLLECTOR, + ANALYTIC, + OTHER +} @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Builder; +import lombok.Data; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * A model class for auditfields + */ +@Data +@Builder +@JsonInclude(JsonInclude.Include.NON_NULL) +public class AuditFields { + + private String createdBy; + private Date createdOn; + private String updatedBy; + private Date updatedOn; + //TODO set default empty values if not exist + private String notes = ""; + private List<String> labels = new ArrayList<>(); + + public void setLabels(Object labels) { + if(labels instanceof List) + this.labels = (List<String>) labels; + } +} @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.deploymentartifact; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Map; + +/** + * A model class which represents Deployment-Artifact entity + */ +@Data +@Document("deployment-artifact") +public class DeploymentArtifact { + + private String id; + + private Integer version; + + private String content; + + private String fileName; + + private DeploymentArtifactStatus status; + + private Map<String, Object> metadata; + + private MsInstanceInfo msInstanceInfo; + + private Map<String, Object> specificationInfo; + +} @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.deploymentartifact; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * A model class to construct a filter that can be passed in DeploymentArtifactSearch + * @see org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch + */ +@Data +public class DeploymentArtifactFilter { + @JsonProperty("release") + private String release; + + @JsonProperty("status") + private DeploymentArtifactStatus status; + + @JsonProperty("tag") + private String tag; +} @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.deploymentartifact; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * A model class to define Deployment-Artifact's searching criteria. + */ +@Data +public class DeploymentArtifactSearch { + + @JsonProperty("filter") + private DeploymentArtifactFilter filter; + + public DeploymentArtifactSearch() { + this.filter = new DeploymentArtifactFilter(); + } +} @@ -0,0 +1,30 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.deploymentartifact; + +/** + * Supported Statuses for a Deployment-Artifact + */ +public enum DeploymentArtifactStatus { + + IN_DEV, NOT_NEEDED, DEV_COMPLETE, + IN_PROD, PROD_FAILED +} @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.deploymentartifact; + +import lombok.Data; + +/** + * MsInstance Reference model used in DeploymentArtifact entity + */ +@Data +public class MsInstanceInfo { + String id; + String name; + String release; +} @@ -0,0 +1,33 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions; + +public class ErrorMessages { + + public static final String MICROSERVICE_NAME_CONFLICT_MESSAGE = "Microservice with this name already exists."; + public static final String MICROSERVICE_TAG_CONFLICT_MESSAGE = "Microservice with this tag name already exists."; + public static final String MS_TAG_NAME_VALIDATION_MESSAGE = + "Microservice tag name is Invalid. Accepts lowercase letters and hyphens." + + " Tag name length cannot exceed 50 characters"; + public static final String MS_SERVICE_NAME_CONFLICT_MESSAGE = "Microservice with this core name already exists."; + public static final String MS_SERVICE_NAME_VALIDATION_MESSAGE = + "Service name is Invalid. Accepts lowercase letters and hyphens"; +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions; + +public class MissingRequestBodyException extends RuntimeException { +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions; + +public class OperationNotAllowedException extends RuntimeException { + public OperationNotAllowedException(String message) { + super(message); + } +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions; + +public class ReleaseNotSupportedException extends RuntimeException{ +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions; + +public class ResourceConflictException extends RuntimeException{ + public ResourceConflictException(String message) { + super(message); + } +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.basemicroservice; + +public class BaseMicroserviceNotFoundException extends RuntimeException { + public BaseMicroserviceNotFoundException(String message) { + super(message); + } +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.basemicroservice; + +public class BaseMicroserviceTagAlreadyExists extends RuntimeException { +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.basemicroservice; + +public class BaseMicroserviceTagInvalid extends RuntimeException { +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.basemicroservice; + +public class BaseMsServiceNameAlreadyExists extends RuntimeException { +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.basemicroservice; + +public class BaseMsServiceNameInvalid extends RuntimeException { +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.common; + +public class UserNotPassedException extends RuntimeException { + public UserNotPassedException(String message) { + super(message); + } +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.deploymentartifact; + +public class BlueprintFileNameCreateException extends RuntimeException{ + public BlueprintFileNameCreateException(String message) { + super(message); + } +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.deploymentartifact; + +public class DeploymentArtifactNotFound extends RuntimeException{ + public DeploymentArtifactNotFound(String message) { + super(message); + } +} @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.deploymentartifact; + +public class StatusChangeNotValidException extends RuntimeException { + + public StatusChangeNotValidException(String message) { + super(message); + } +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.msinstance; + +public class MsInstanceAlreadyExistsException extends RuntimeException { +} @@ -0,0 +1,27 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.msinstance; + +public class MsInstanceNotFoundException extends RuntimeException{ + public MsInstanceNotFoundException(String message) { + super(message); + } +} @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.specification; + +import java.util.Map; + +public class SpecificationInvalid extends RuntimeException { + + Map<String, Object> errorsMap; + + public SpecificationInvalid(String message) { + super(message); + } + + public SpecificationInvalid(Map<String, Object> errorsMap){ + this.errorsMap = errorsMap; + } + + +} @@ -0,0 +1,24 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.exceptions.specification; + +public class SpecificationNotFoundException extends RuntimeException { +} @@ -0,0 +1,36 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.microserviceinstance; + +import lombok.Data; + +import java.util.List; + +/** + * DeploymentArtifacts Reference model used in Microservice-Instance entity + */ +@Data +public class DeploymentArtifactsRef { + + private int mostRecentVersion; + private List<String> deploymentArtifacts; + +} @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.DBRef; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Map; + +/** + * A model class which represents Microservice-Instance entity + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Document("ms-instance") +public class MsInstance { + @Id + private String id; + private String name; + private String release; + private String version; + private MsInstanceStatus status; + private Map<String, Object> metadata; + private Map<String,Object> msInfo; + + @DBRef + private Specification activeSpec; + + private DeploymentArtifactsRef deploymentArtifactsInfo; +}
\ No newline at end of file @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.microserviceinstance; + +/** + * Supported Statuses for Microservice-Instance entity + */ +public enum MsInstanceStatus { + NEW, IN_DEV, DEV_COMPLETE, IN_TEST, CERTIFIED, PROD_DEPLOYED +} @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.Map; + +/** + * A model that represent request body to patch DeploymentArtifact entity. + */ +@Data +public class DeploymentArtifactPatchRequest { + + @JsonProperty("status") + private DeploymentArtifactStatus status; + + @JsonProperty("metadata") + private Map<String, Object> metaData; +} @@ -0,0 +1,35 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * A model that represent response body to send a simple error response. + */ +@Data +@AllArgsConstructor +public class ErrorResponse { + + private String message; + +} @@ -0,0 +1,54 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import lombok.Data; +import org.springframework.http.HttpStatus; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * A model that represent response body to send a detailed error response. + */ +@Data +public class GenericErrorResponse { + private List<String> errors = new ArrayList<>(); + private HttpStatus status; + private String message; + + public GenericErrorResponse() { + } + + public GenericErrorResponse(List<String> errors, HttpStatus status, String message) { + this.errors = errors; + this.status = status; + this.message = message; + } + + public GenericErrorResponse(String error, HttpStatus status, String message) { + this.status = status; + this.message = message; + errors = Arrays.asList(error); + } + +} @@ -0,0 +1,59 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsLocation; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsType; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import java.util.Map; + +/** + * A model that represent request body to create a Microservice entity. + */ +@NoArgsConstructor +@Data +public class MicroserviceCreateRequest { + + @NotBlank(message = "Microservice tag can not be blank") + @Pattern(regexp = "^([a-z0-9](-[a-z0-9])*)+$", message = "Microservice tag name is Invalid. Accepts alphanumerics and hyphens.") + @Size(min = 5, max = 50, message = "Tag name length cannot exceed 50 characters") + private String tag; + + @NotBlank(message = "Microservice name cannot be blank") + private String name; + + @Pattern(regexp = "^[a-z-]*$", message = "Microservice core name is Invalid. Accepts lowercase letters and hyphens.") + private String serviceName; + + private BaseMsType type; + private BaseMsLocation location; + private String namespace; + private Map<String, Object> metadata; + + @NotBlank(message = "user can not be blank") + private String user; + +} @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsLocation; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsType; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import java.util.Map; + +/** + * A model that represent request body to update a Microservice entity. + */ +@NoArgsConstructor +@Data +public class MicroserviceUpdateRequest { + + @Pattern(regexp = "^(?!\\s*$).+", message = "must not be blank") + private String name; + + @Pattern(regexp = "^[a-z-]*$", message = "Microservice core name is Invalid. Accepts lowercase letters and hyphens.") + private String serviceName; + + private BaseMsType type; + private BaseMsLocation location; + private String namespace; + private Map<String, Object> metadata; + + @NotBlank(message = "user cannot be blank") + private String user; +} @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import java.util.Map; + +/** + * A model that represent request body to create MsInsance entity. + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class MsInstanceRequest { + + @NotBlank + private String name; + + @NotBlank + private String release; + + private String version; + + @NotBlank + private String user; + + private Map<String,Object> metadata; +} @@ -0,0 +1,42 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.Map; + +/** + * A model that represent request body to patch MsInstance entity. + */ +@Data +public class MsInstanceUpdateRequest { + + private String release; + private String version; + private Map<String,Object> metadata; + + @NotBlank(message = "User cannot be blank.") + private String user; +} + + @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Map; + +/** + * A model that represent request body to create Specification entity. + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SpecificationRequest { + + private Map<String,Object> specContent; + private Map<String, Object> policyJson; + private DeploymentType type; + private String user; + private Map<String,Object> metadata; +} @@ -0,0 +1,34 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.restapi; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * A model that represent a simple Success response body. + */ +@Data +@AllArgsConstructor +public class SuccessResponse { + + private String message; +} @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.specification; + +/** + * Supported Deployment Types in Specification entity + */ +public enum DeploymentType { + K8S, DOCKER +} @@ -0,0 +1,52 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.specification; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.util.Map; + +/** + * A model class which represents Specification entity + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@JsonInclude(JsonInclude.Include.NON_NULL) +@Document("specification") +public class Specification { + + @Id + private String id; + private SpecificationStatus status; + private Map<String,Object> specContent; + private Map<String, Object> policyJson; + private DeploymentType type; + private Map<String,Object> metadata; + private Map<String,Object> msInstanceInfo; +} @@ -0,0 +1,28 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.model.specification; + +/** + * Supported statuses for Specification entity + */ +public enum SpecificationStatus { + ACTIVE, INACTIVE +} @@ -0,0 +1,71 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.BaseMicroserviceGateway; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +/** + * Mongo implementation of BaseMicroserviceGateway + */ +@Service +public class BaseMicroserviceMongoGateway implements BaseMicroserviceGateway { + + @Autowired + BaseMicroserviceMongoRepo repo; + + @Override + public Optional<BaseMicroservice> findByName(String name) { + return repo.findByNameIgnoreCase(name); + } + + @Override + public Optional<BaseMicroservice> findByTag(String tag) { + return repo.findByTagIgnoreCase(tag); + } + + @Override + public Optional<BaseMicroservice> findByServiceName(String serviceName) { + return repo.findByServiceNameIgnoreCase(serviceName); + } + + @Override + public BaseMicroservice save(BaseMicroservice microservice) { + return repo.save(microservice); + } + + @Override + public List<BaseMicroservice> findAll() { + Sort sortByCreatedDate = Sort.by(Sort.Direction.DESC, "metadata.createdOn"); + return repo.findAll(sortByCreatedDate); + } + + @Override + public Optional<BaseMicroservice> findById(String msId) { + return Optional.empty(); + } +} @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * An interface to use Spring MongoRepository + */ +@Repository +public interface BaseMicroserviceMongoRepo extends MongoRepository<BaseMicroservice, String> { + + Optional<BaseMicroservice> findByNameIgnoreCase(String name); + + Optional<BaseMicroservice> findByTagIgnoreCase(String tag); + + Optional<BaseMicroservice> findByServiceNameIgnoreCase(String serviceName); +} @@ -0,0 +1,86 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.MsInstanceInfo; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactGateway; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +/** + * Mongo implementation of BaseMicroserviceGateway + */ +@Service +public class DeploymentArtifactMongoGateway implements DeploymentArtifactGateway { + + @Autowired + DeploymentArtifactMongoRepo crudRepo; + + public DeploymentArtifactMongoGateway(DeploymentArtifactMongoRepo repo) { + this.crudRepo = repo; + } + + @Override + public List<DeploymentArtifact> findAll() { + return crudRepo.findAll(); + } + + @Override + public List<DeploymentArtifact> findByMsInstanceId(String id) { + return crudRepo.findByMsInstanceInfo_Id(id); + } + + @Override + public Optional<DeploymentArtifact> findById(String id) { + return crudRepo.findById(id); + } + + @Override + public void deleteById(String deploymentArtifactId) { + crudRepo.deleteById(deploymentArtifactId); + } + + @Override + public DeploymentArtifact save(DeploymentArtifact deploymentArtifact) { + return crudRepo.save(deploymentArtifact); + } + + @Override + public List<DeploymentArtifact> findAll(DeploymentArtifactSearch search) { + DeploymentArtifact artifact = new DeploymentArtifact(); + artifact.setStatus(search.getFilter().getStatus()); + //Currently searching tag in filename as it is not present in DeploymentArtifact record + artifact.setFileName(search.getFilter().getTag()); + + MsInstanceInfo msInstanceInfo = new MsInstanceInfo(); + msInstanceInfo.setRelease(search.getFilter().getRelease()); + artifact.setMsInstanceInfo(msInstanceInfo); + + return crudRepo.findAll(Example.of(artifact,ExampleMatcher.matching().withIgnoreCase())); + } +} @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * An interface to use Spring MongoRepository + */ +@Repository +public interface DeploymentArtifactMongoRepo extends MongoRepository<DeploymentArtifact, String> { + + List<DeploymentArtifact> findByMsInstanceInfo_Id(String id); + +} @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceGateway; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Optional; + +/** + * Mongo implementation of MsInstance + */ +@Service +public class MsInstanceMongoGateway implements MsInstanceGateway { + + @Autowired + private MsInstanceMongoRepo repo; + + @Override + public Optional<MsInstance> findByNameAndRelease(String name, String release) { + return repo.findByNameIgnoreCaseAndReleaseIgnoreCase(name, release); + } + + @Override + public Optional<MsInstance> findById(String msInstanceId) { + return repo.findById(msInstanceId); + } + + @Override + public List<MsInstance> findAll() { + Sort sortByCreatedDate = Sort.by(Sort.Direction.DESC, "metadata.createdOn"); + return repo.findAll(sortByCreatedDate); + } + + @Override + public MsInstance save(MsInstance msInstance) { + return repo.save(msInstance); + } +} @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +/** + * An interface to use Spring MongoRepository + */ +@Repository +public interface MsInstanceMongoRepo extends MongoRepository<MsInstance, String> { + + Optional<MsInstance> findByNameIgnoreCaseAndReleaseIgnoreCase(String name, String release); + + +} @@ -0,0 +1,48 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.specification; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationGateway; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * Mongo implementation of Specification + */ +@Service +public class SpecificationMongoGateway implements SpecificationGateway { + + @Autowired + private SpecificationMongoRepo repo; + + @Override + public List<Specification> getSpecificationByMsInstanceId(String id) { + return repo.getSpecificationsByMsInstaceId(id); + } + + @Override + public Specification save(Specification newSpec) { + return repo.save(newSpec); + } +} @@ -0,0 +1,38 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.mongo.specification; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.mongodb.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * An interface to use Spring MongoRepository + */ +@Repository +public interface SpecificationMongoRepo extends MongoRepository<Specification, String> { + + @Query(value = "{'msInstanceInfo.id':?0}") + List<Specification> getSpecificationsByMsInstaceId(String id); +} @@ -0,0 +1,149 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.controller; + +import org.onap.dcaegen2.platform.mod.model.exceptions.MissingRequestBodyException; +import org.onap.dcaegen2.platform.mod.model.exceptions.OperationNotAllowedException; +import org.onap.dcaegen2.platform.mod.model.exceptions.ResourceConflictException; +import org.onap.dcaegen2.platform.mod.model.exceptions.basemicroservice.BaseMicroserviceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.exceptions.common.UserNotPassedException; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.DeploymentArtifactNotFound; +import org.onap.dcaegen2.platform.mod.model.exceptions.msinstance.MsInstanceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.exceptions.specification.SpecificationInvalid; +import org.onap.dcaegen2.platform.mod.model.restapi.ErrorResponse; +import org.onap.dcaegen2.platform.mod.model.restapi.GenericErrorResponse; +import com.fasterxml.jackson.core.JsonParseException; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.reactive.function.client.WebClientResponseException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * a class to manage all exceptions + */ +@ControllerAdvice +@Slf4j +public class AppExceptionHandler { + + @ExceptionHandler(value = {WebClientResponseException.class}) + public ResponseEntity<ErrorResponse> handleCompSpecInvalidException + (WebClientResponseException ex, WebRequest request) { + return new ResponseEntity<ErrorResponse> + (new ErrorResponse(ex.getResponseBodyAsString()), HttpStatus.INTERNAL_SERVER_ERROR); + } + + @ExceptionHandler(value = {JsonParseException.class}) + public ResponseEntity<GenericErrorResponse> handleJsonParsedException + (JsonParseException ex, WebRequest request) { + + GenericErrorResponse response = new GenericErrorResponse(); + response.setStatus(HttpStatus.BAD_REQUEST); + response.setMessage("Invalid JSON request body format."); + response.setErrors(Arrays.asList(ex.getMessage())); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<GenericErrorResponse> specificationInvalid(SpecificationInvalid ex) { + Map<String, Object> errorResponse = new Gson().fromJson(ex.getMessage(), Map.class); + GenericErrorResponse response = new GenericErrorResponse(); + response.setMessage((String) errorResponse.get("summary")); + response.setStatus(HttpStatus.BAD_REQUEST); + response.setErrors((List<String>) errorResponse.get("errors")); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<GenericErrorResponse> missingRequestBodyException(MissingRequestBodyException ex){ + GenericErrorResponse response = new GenericErrorResponse(); + response.setMessage("Missing paramaters"); + response.setStatus(HttpStatus.BAD_REQUEST); + response.setErrors(Arrays.asList("Missing required request body paramaters")); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveUserNotPassedException(UserNotPassedException ex){ + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveMsInstanceNotFoundException(MsInstanceNotFoundException ex) { + log.error(ex.getMessage()); + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveDeploymentArtifactNotFound(DeploymentArtifactNotFound ex) { + log.error(ex.getMessage()); + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), + HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveOperationNotAllowed(OperationNotAllowedException ex) { + log.error(ex.getMessage()); + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), + HttpStatus.CONFLICT); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveResourceConflict(ResourceConflictException ex) { + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.CONFLICT); + } + + @ExceptionHandler(value = {BaseMicroserviceNotFoundException.class}) + public ResponseEntity<ErrorResponse> resolveResourceNotFoundExcetions(RuntimeException ex) { + log.error(ex.getMessage(), ex); + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), HttpStatus.CONFLICT); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity<GenericErrorResponse> resolveBeanValidationException(MethodArgumentNotValidException ex){ + log.error(ex.getMessage()); + GenericErrorResponse response = new GenericErrorResponse(); + response.setMessage("Validation failed."); + response.setStatus(HttpStatus.BAD_REQUEST); + response.setErrors(getBeanValidationErrors(ex)); + return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); + } + + private List<String> getBeanValidationErrors(MethodArgumentNotValidException ex) { + List<String> errors = new ArrayList<>(); + ex.getBindingResult().getAllErrors().forEach((error) -> { + String fieldName = ((FieldError) error).getField(); + String errorMessage = error.getDefaultMessage(); + errors.add(String.format("%s: %s", fieldName, errorMessage)); + }); + return errors; + } +} @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.controller; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.MsService; +import io.swagger.annotations.Api; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; + +import static org.onap.dcaegen2.platform.mod.web.controller.BaseMicroserviceController.API_BASE_MICROSERVICE; + +/** + * Controller class to manage Microservice's REST endpoints + */ +@CrossOrigin +@RestController +@RequestMapping(API_BASE_MICROSERVICE) +@Api(tags = "Base Microservice", description = "APIs to manage Base Microservice") +public class BaseMicroserviceController { + + public static final String API_BASE_MICROSERVICE = "/api/base-microservice"; + @Autowired + @Setter + MsService baseMsService; + + @GetMapping + public List<BaseMicroservice> getAll() { + return baseMsService.getAllMicroservices(); + } + + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public BaseMicroservice createMicroservice(@RequestBody @Valid MicroserviceCreateRequest request) { + return baseMsService.createMicroservice(request); + } + + @PatchMapping(value = "/{msId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void updateMicroservice(@RequestBody @Valid MicroserviceUpdateRequest request, + @PathVariable("msId") String msId){ + baseMsService.updateMicroservice(msId, request); + } +} @@ -0,0 +1,115 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.controller; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.BlueprintFileNameCreateException; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.StatusChangeNotValidException; +import org.onap.dcaegen2.platform.mod.model.restapi.DeploymentArtifactPatchRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.ErrorResponse; +import org.onap.dcaegen2.platform.mod.model.restapi.SuccessResponse; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import io.swagger.annotations.Api; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.Arrays; +import java.util.List; + +import static org.onap.dcaegen2.platform.mod.web.controller.DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL; + +/** + * Controller class to manage DeploymentArtifact's REST endpoints + */ +@RestController +@CrossOrigin +@RequestMapping(DEPLOYMENT_ARTIFACTS_BASE_URL) +@Slf4j +@Api(tags = "Deployment Artifact", value = "APIs to manage Deployment Artifacts") +public class DeploymentArtifactController { + + public static final String DEPLOYMENT_ARTIFACTS_BASE_URL = "/api/deployment-artifact"; + + public static final String GET_STATUSES = "/statuses"; + + @Autowired + private DeploymentArtifactService service; + + @PostMapping("/{msInstanceId}") + @ResponseStatus(HttpStatus.CREATED) + public DeploymentArtifact generateDeploymentArtifactForMSInstance(@PathVariable String msInstanceId, + @RequestParam String user ){ + return service.generateDeploymentArtifact(msInstanceId, user); + } + + @GetMapping + @ResponseStatus(HttpStatus.OK) + public List<DeploymentArtifact> getAllDeploymentArtifacts(){ + return service.getAllDeploymentArtifacts(); + } + + @PostMapping("/search") + @ResponseStatus(HttpStatus.OK) + public List<DeploymentArtifact> searchDeploymentArtifacts(@RequestBody DeploymentArtifactSearch searchRequest){ + log.info("Search on deployment artifacts: {}", searchRequest); + return service.searchDeploymentArtifacts(searchRequest); + } + + @GetMapping(GET_STATUSES) + @ResponseStatus(HttpStatus.OK) + public List<DeploymentArtifactStatus> getDeploymentArtifactStatuses(){ + return Arrays.asList(DeploymentArtifactStatus.values()); + } + + @PatchMapping(value = "/{deploymentArtifactId}", params = {"user!="}) + public ResponseEntity<SuccessResponse> patchDeploymentArtifact(@PathVariable("deploymentArtifactId") String id, + @RequestBody DeploymentArtifactPatchRequest deploymentArtifactPatchRequest, + @RequestParam("user") String user){ + log.info("***Received request {} to update DeploymentArtifact id {} by {}", deploymentArtifactPatchRequest, id, user); + service.updateDeploymentArtifact(id, deploymentArtifactPatchRequest, user); + return new ResponseEntity<>(new SuccessResponse("Deployment Artifact was updated."),HttpStatus.OK); + } + + @DeleteMapping( value = "/{deploymentArtifactId}", params = {"user!="}) + public ResponseEntity<SuccessResponse> deleteDeploymentArtifact(@PathVariable("deploymentArtifactId") String id, + @RequestParam("user") String user){ + log.info("***Received request to delete DeploymentArtifact id {} by {}", id, user); + service.deleteDeploymentArtifact(id); + return new ResponseEntity<>(new SuccessResponse("Deployment Artifact was deleted"), HttpStatus.OK); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveBaseMsServiceNameRegex(BlueprintFileNameCreateException ex) { + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), + HttpStatus.BAD_REQUEST); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveStatusValidationFailure(StatusChangeNotValidException ex) { + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), + HttpStatus.BAD_REQUEST); + } +} @@ -0,0 +1,75 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.controller; + +import org.onap.dcaegen2.platform.mod.model.exceptions.msinstance.MsInstanceAlreadyExistsException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.ErrorResponse; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceUpdateRequest; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * Controller class to manage MicroserviceInstance's REST endpoints + */ +@CrossOrigin +@RestController +@Api(tags = "Microservice Instance", description = "APIs to manage Microservice Instance") +@RequestMapping("/api/microservice-instance") +public class MicroserviceInstanceController { + + @Autowired + MsInstanceService msInstanceService; + + @GetMapping + @ApiOperation("Get all Microservices Instances") + public List<MsInstance> getAll() { + return msInstanceService.getAll(); + } + + + @PostMapping("/{msName}") + @ApiOperation("Create a Microservice Instance") + @ResponseStatus(HttpStatus.CREATED) + public MsInstance createMsInstance(@PathVariable String msName, @RequestBody MsInstanceRequest request) { + return msInstanceService.createMicroserviceInstance(msName, request); + } + + @PatchMapping("/{msId}") + @ApiOperation("Patch a Microservice Instance") + @ResponseStatus(HttpStatus.OK) + public MsInstance patchMsInstance(@RequestBody MsInstanceUpdateRequest request, @PathVariable String msId){ + return msInstanceService.updateMsInstance(request, msId); + } + + @ExceptionHandler + public ResponseEntity<ErrorResponse> resolveMsInstanceConflict(MsInstanceAlreadyExistsException ex) { + return new ResponseEntity<>(new ErrorResponse("Microservice Instance for the given name and release already exists"), HttpStatus.CONFLICT); + } +} @@ -0,0 +1,62 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.controller; + +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * Controller class to manage Specification's REST endpoints + */ +@CrossOrigin +@RestController +@Api(tags = "Component Specification", description = "APIs to manage Component Specifications") +@RequestMapping("/api/specification") +@Slf4j +public class SpecificationController { + + @Autowired + SpecificationService specificationService; + + @GetMapping("/{msInstanceId}") + @ApiOperation("Get all specifications for a Microservice Instance") + public List<Specification> getAllSpecsByMsInstanceId(@PathVariable String msInstanceId) { + log.info(msInstanceId); + return specificationService.getAllSpecsByMsInstanceId(msInstanceId); + } + + @PostMapping("/{msInstanceId}") + @ApiOperation("Create Specification for a Microservice Instance") + @ResponseStatus(HttpStatus.CREATED) + public Specification createSpecification(@PathVariable String msInstanceId, @RequestBody SpecificationRequest request) { + log.info(request.toString()); + return specificationService.createSpecification(msInstanceId, request); + } +} @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +/** + * An interface to interact with BaseMicroservice persistence + */ +public interface BaseMicroserviceGateway { + + List<BaseMicroservice> findAll(); + + Optional<BaseMicroservice> findByName(String name); + + Optional<BaseMicroservice> findByTag(String tag); + + Optional<BaseMicroservice> findByServiceName(String serviceName); + + BaseMicroservice save(BaseMicroservice microservice); + + Optional<BaseMicroservice> findById(String msId); +}
\ No newline at end of file @@ -0,0 +1,47 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; + +import java.util.List; + +/** + * An interface to access Ms Services + */ +public interface MsService { + BaseMicroservice createMicroservice(MicroserviceCreateRequest microserviceRequest); + + List<BaseMicroservice> getAllMicroservices(); + + BaseMicroservice getMicroserviceById(String baseMsId); + + BaseMicroservice getMicroserviceByName(String msName); + + void updateMicroservice(String requestedMsId, MicroserviceUpdateRequest updateRequest); + + void saveMsInstanceReferenceToMs(BaseMicroservice microservice, MsInstance msInstance); + + void updateMsInstanceRef(MsInstance msInstance); +} @@ -0,0 +1,257 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.basemicroservice; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsStatus; +import org.onap.dcaegen2.platform.mod.model.common.AuditFields; +import org.onap.dcaegen2.platform.mod.model.exceptions.ErrorMessages; +import org.onap.dcaegen2.platform.mod.model.exceptions.ResourceConflictException; +import org.onap.dcaegen2.platform.mod.model.exceptions.basemicroservice.BaseMicroserviceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * MsService implementation + */ +@Service +public class MsServiceImpl implements MsService { + + @Autowired + @Setter + private BaseMicroserviceGateway repository; + + @Autowired + @Setter + private MsInstanceService msInstanceService; + + /** + * creates Microservice record + * @param microserviceRequest + * @return + */ + @Override + public BaseMicroservice createMicroservice(MicroserviceCreateRequest microserviceRequest) { + checkIfThereAreAnyConflicts(microserviceRequest); //TODO: Make fields unique in entity itself + BaseMicroservice microservice = new BaseMsCreator().create(microserviceRequest); + return repository.save(microservice); + } + + /** + * name, tag and serviceName are unique for the given ms. This method make sure that. + * */ + private void checkIfThereAreAnyConflicts(MicroserviceCreateRequest microserviceRequest) { + checkIfMsNameAlreadyExists(microserviceRequest.getName()); + checkIfMsTagAlreadyExists(microserviceRequest.getTag()); + checkiIfServiceNameAlreadyExists(microserviceRequest.getServiceName()); + } + + private void checkIfMsNameAlreadyExists(String msName) { + if (repository.findByName(msName).isPresent()) + throw new ResourceConflictException(ErrorMessages.MICROSERVICE_NAME_CONFLICT_MESSAGE); + } + + private void checkIfMsTagAlreadyExists(String msTag) { + if (repository.findByTag(msTag).isPresent()) + throw new ResourceConflictException(ErrorMessages.MICROSERVICE_TAG_CONFLICT_MESSAGE); + } + + private void checkiIfServiceNameAlreadyExists(String serviceName) { + boolean serviceNameIsEmpty = serviceName == null || serviceName.isEmpty(); + if(serviceNameIsEmpty) + return; + if (repository.findByServiceName(serviceName).isPresent()) + throw new ResourceConflictException(ErrorMessages.MS_SERVICE_NAME_CONFLICT_MESSAGE); + } + + /** + * lists all microservice records + * @return + */ + @Override + public List<BaseMicroservice> getAllMicroservices() { + return repository.findAll(); + } + + /** + * gets a Mioroservice by id + * @param baseMsId + * @return + */ + @Override + public BaseMicroservice getMicroserviceById(String baseMsId) { + return repository.findById(baseMsId).orElseThrow(() -> + new BaseMicroserviceNotFoundException(String.format("Microservice with id %s not found", baseMsId))); + } + + /** + * gets a Microservice by name + * @param msName + * @return + */ + @Override + public BaseMicroservice getMicroserviceByName(String msName) { + return repository.findByName(msName).orElseThrow(() -> + new BaseMicroserviceNotFoundException(String.format("Microservice with name %s not found", msName))); + } + + /** + * updates a Microservice + * @param requestedMsId + * @param updateRequest + */ + @Override + public void updateMicroservice(String requestedMsId, MicroserviceUpdateRequest updateRequest) { + BaseMicroservice microservice = getMicroserviceById(requestedMsId); + updateMetadata(updateRequest, microservice); + updateOtherFields(updateRequest, microservice); + repository.save(microservice); + msInstanceService.updateMicroserviceReference(microservice); + } + + //TODO: Get rid of nulls! + private void updateMetadata(MicroserviceUpdateRequest updateRequest, BaseMicroservice microservice) { + if(updateRequest.getUser() != null){ + microservice.getMetadata().setUpdatedBy(updateRequest.getUser()); + } + if(updateRequest.getMetadata() != null && updateRequest.getMetadata().containsKey("notes")){ + microservice.getMetadata().setNotes((String) updateRequest.getMetadata().get("notes")); + } + if(updateRequest.getMetadata() != null && updateRequest.getMetadata().containsKey("labels")){ + microservice.getMetadata().setLabels((List<String>) updateRequest.getMetadata().get("labels")); + } + microservice.getMetadata().setUpdatedOn(new Date()); + } + + private void updateOtherFields(MicroserviceUpdateRequest updateRequest, BaseMicroservice microservice) { + if(updateRequest.getName() != null){ + updateName(updateRequest, microservice); + } + if(updateRequest.getType() != null){ + microservice.setType(updateRequest.getType()); + } + if(updateRequest.getLocation() != null){ + microservice.setLocation(updateRequest.getLocation()); + } + if(updateRequest.getServiceName() != null){ + updateServiceName(updateRequest, microservice); + } + if(updateRequest.getNamespace() != null){ + microservice.setNamespace(updateRequest.getNamespace()); + } + } + + /** + * If name requested in the updateRequest doesn't match the name of the ms record which is being worked on, + * then only check for the uniqueness. + */ + private void updateName(MicroserviceUpdateRequest updateRequest, BaseMicroservice microservice) { + boolean notMatchesWithCurrentName = !updateRequest.getName().equals(microservice.getName()); + if(notMatchesWithCurrentName) + checkIfMsNameAlreadyExists(updateRequest.getName()); + microservice.setName(updateRequest.getName()); + } + + /** + * If serviceName requested in the updateRequest doesn't match the serviceName of the ms record which is + * being worked on, then only check for the uniqueness. + */ + private void updateServiceName(MicroserviceUpdateRequest updateRequest, BaseMicroservice microservice) { + boolean notMatchesWithCurrentServiceName = !updateRequest.getServiceName().equals(microservice.getServiceName()); + if(notMatchesWithCurrentServiceName) + checkiIfServiceNameAlreadyExists(updateRequest.getServiceName()); + microservice.setServiceName(updateRequest.getServiceName()); + } + + /** + * saves msInstance reference in a given Microservice + * @param microservice + * @param msInstance + */ + @Override + public void saveMsInstanceReferenceToMs(BaseMicroservice microservice, MsInstance msInstance) { + microservice.getMsInstances().add(getMsInstanceReference(msInstance)); + repository.save(microservice); + } + + /** + * updates MsIntstance ref in Microservice record + * @param msInstance + */ + @Override + public void updateMsInstanceRef(MsInstance msInstance) { + BaseMicroservice microservice = getMicroserviceById((String) msInstance.getMsInfo().get("id")); + List<Map<String, String>> msInstancesRef = microservice.getMsInstances(); + msInstancesRef.forEach((ref) -> { + if(ref.get("id").equals(msInstance.getId())) + ref.put("name", msInstance.getName()); + }); + repository.save(microservice); + } + + private Map<String, String> getMsInstanceReference(MsInstance msInstance) { + Map<String,String> msInstanceInfo = new HashMap<>(); + msInstanceInfo.put("id", msInstance.getId()); + msInstanceInfo.put("name", msInstance.getName()); + return msInstanceInfo; + } + + private class BaseMsCreator { + + BaseMicroservice create(MicroserviceCreateRequest createRequest) { + BaseMicroservice microservice = new BaseMicroservice(); + microservice.setLocation(createRequest.getLocation()); + microservice.setName(createRequest.getName()); + microservice.setTag(createRequest.getTag()); + microservice.setServiceName(createRequest.getServiceName()); + microservice.setNamespace(createRequest.getNamespace()); + microservice.setStatus(BaseMsStatus.ACTIVE); + microservice.setType(createRequest.getType()); + microservice.setMetadata(getMetadataFields(createRequest)); + return microservice; + } + + private AuditFields getMetadataFields(MicroserviceCreateRequest request) { + AuditFields auditFields = AuditFields.builder().build(); + auditFields.setCreatedBy(request.getUser()); + auditFields.setCreatedOn(new Date()); + + if (request.getMetadata().containsKey("notes")) + auditFields.setNotes((String) request.getMetadata().get("notes")); + if (request.getMetadata().containsKey("labels")) +// auditFields.setLabels((List<String>) request.getMetadata().get("labels")); + auditFields.setLabels(request.getMetadata().get("labels")); + + return auditFields; + + } + } +} @@ -0,0 +1,59 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.BlueprintFileNameCreateException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.springframework.stereotype.Component; + +/** + * A name creator for Deployment Artifact files. + */ +@Component +public class ArtifactFileNameCreator { + + private static final String FILE_FORMAT = ".yaml"; + + /** + * creates a file name + * @param msInstance + * @param version + * @return + */ + public String createFileName(MsInstance msInstance, int version) { + if(msInstance.getMsInfo() == null || !msInstance.getMsInfo().containsKey("tag")){ + throwException("MS-tag"); + } + if(msInstance.getActiveSpec() == null){ + throwException("active-spec"); + } + return msInstance.getMsInfo().get("tag") + "_" + + msInstance.getActiveSpec().getType().toString().toLowerCase() + "_" + + msInstance.getRelease() + "_" + + version + + FILE_FORMAT; + } + + private void throwException(String missingProperty) { + throw new BlueprintFileNameCreateException("Can not create bluerprint file name: " + + missingProperty + " is missing"); + } +} @@ -0,0 +1,45 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; + +import java.util.List; +import java.util.Optional; + + /** + * An interface to interact with DeploymentArtifact persistence + */ +public interface DeploymentArtifactGateway { + + List<DeploymentArtifact> findAll(); + + List<DeploymentArtifact> findByMsInstanceId(String id); + + Optional<DeploymentArtifact> findById(String id); + + void deleteById(String deploymentArtifactId); + + DeploymentArtifact save(DeploymentArtifact deploymentArtifact); + + List<DeploymentArtifact> findAll(DeploymentArtifactSearch search); +} @@ -0,0 +1,32 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; + +import java.util.Map; + +/** + * provides abstraction to generate Deployment Artifacts + */ +public interface DeploymentArtifactGeneratorStrategy { + Map<String, Object> generateForRelease(Specification activeSpec, String release); +} @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.DeploymentArtifactPatchRequest; + +import java.util.List; + +/** + * An interface to access DeploymentArtifact Services + */ +public interface DeploymentArtifactService { + + DeploymentArtifact generateDeploymentArtifact(String msInstanceId, String user); + + List<DeploymentArtifact> getAllDeploymentArtifacts(); + + DeploymentArtifact findDeploymentArtifactById(String id); + + void updateDeploymentArtifact(String deploymentArtifactId, DeploymentArtifactPatchRequest deploymentArtifactPatchRequest, String user); + + List<DeploymentArtifact> findByMsInstanceId(String msInstanceId); + + void deleteDeploymentArtifact(String deploymentArtifactId); + + void updateMsInstanceRef(MsInstance msInstance); + + List<DeploymentArtifact> searchDeploymentArtifacts(DeploymentArtifactSearch search); +} + @@ -0,0 +1,205 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.MsInstanceInfo; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.DeploymentArtifactNotFound; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.DeploymentArtifactsRef; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.DeploymentArtifactPatchRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +/** + * DeploymentArtifact Service implementation + */ +@Service +@Slf4j +@Setter +public class DeploymentArtifactServiceImpl implements DeploymentArtifactService{ + + private static final String VERSION_KEY = "mostRecentVersion"; + + @Autowired + private MsInstanceService msInstanceService; + + @Autowired + private DeploymentArtifactGeneratorStrategy deploymentArtifactGeneratorStrategy; + + @Autowired + private DeploymentArtifactGateway deploymentArtifactGateway; + + @Autowired + private ArtifactFileNameCreator fileNameCreator; + + @Autowired + private DeploymentArtifactStatusChangeHandler statusChangeHandler; + + ///////////////FIND METHODS////////////////////////// + @Override + public List<DeploymentArtifact> getAllDeploymentArtifacts() { + return deploymentArtifactGateway.findAll(); + } + + @Override + public List<DeploymentArtifact> searchDeploymentArtifacts(DeploymentArtifactSearch search) { + return deploymentArtifactGateway.findAll(search); + } + + @Override + public DeploymentArtifact findDeploymentArtifactById(String id){ + return deploymentArtifactGateway.findById(id).orElseThrow( + () -> new DeploymentArtifactNotFound("Deployment Artifact with id " + id + " not found") + ); + } + + @Override + public List<DeploymentArtifact> findByMsInstanceId(String msInstanceId) { + return deploymentArtifactGateway.findByMsInstanceId(msInstanceId); + } + + @Override + @Transactional + public void deleteDeploymentArtifact(String deploymentArtifactId) { + DeploymentArtifact deploymentArtifact = findDeploymentArtifactById(deploymentArtifactId); + log.info("deleting {}", deploymentArtifact.getFileName()); + deploymentArtifactGateway.deleteById(deploymentArtifactId); + msInstanceService.removeDeploymentArtifactFromMsInstance(deploymentArtifact); + } + + @Override + @Transactional + public void updateMsInstanceRef(MsInstance msInstance) { + List<DeploymentArtifact> deploymentArtifacts = findByMsInstanceId(msInstance.getId()); + deploymentArtifacts.forEach((deploymentArtifact) -> { + deploymentArtifact.getMsInstanceInfo().setName(msInstance.getName()); + deploymentArtifact.getMsInstanceInfo().setRelease(msInstance.getRelease()); + deploymentArtifactGateway.save(deploymentArtifact); + }); + } + + ////////////////////////////////////////////////////// + + @Override + @Transactional + //only status update was implemented + public void updateDeploymentArtifact(String deploymentArtifactId, DeploymentArtifactPatchRequest deploymentArtifactPatchRequest, + String user) { + DeploymentArtifact deploymentArtifact = findDeploymentArtifactById(deploymentArtifactId); + updateStatus(deploymentArtifactPatchRequest, deploymentArtifact); + updateMetadata(user, deploymentArtifact); + log.info("Updating the artifact in database.."); + deploymentArtifactGateway.save(deploymentArtifact); + msInstanceService.updateStatusBasedOnDeploymentArtifactsStatuses(deploymentArtifact.getMsInstanceInfo().getId()); + } + + private void updateMetadata(String user, DeploymentArtifact deploymentArtifact) { + deploymentArtifact.getMetadata().put("updatedBy", user); + deploymentArtifact.getMetadata().put("updatedOn", new Date()); + } + + private void updateStatus(DeploymentArtifactPatchRequest deploymentArtifactPatchRequest, DeploymentArtifact deploymentArtifact) { + DeploymentArtifactStatus changeToStatus = deploymentArtifactPatchRequest.getStatus(); + if(changeToStatus != null){ + log.info("Sent request to deployment artifact status change handler: {}", changeToStatus); + statusChangeHandler.handleStatusChange(changeToStatus, deploymentArtifact); + } + } + + @Override + @Transactional + public DeploymentArtifact generateDeploymentArtifact(String msInstanceId, String user) { + MsInstance msInstance = msInstanceService.getMsInstanceById(msInstanceId); + + //Generate the Blueprint for the active specification for the instance + Map<String, Object> deploymentArtifact = deploymentArtifactGeneratorStrategy.generateForRelease(msInstance.getActiveSpec(), msInstance.getRelease()); + + DeploymentArtifact artifact = new DeploymentArtifact(); + artifact.setContent(String.valueOf(deploymentArtifact.get("content"))); + artifact.setVersion(updateLatestVersion(msInstance.getDeploymentArtifactsInfo())); + artifact.setStatus(DeploymentArtifactStatus.IN_DEV); + artifact.setMsInstanceInfo(createMsInstanceReferenceInfo(msInstance)); + artifact.setSpecificationInfo(createSpecificationReferenceInfo(msInstance.getActiveSpec())); + artifact.setMetadata(createMetadata(user)); + + artifact.setFileName(fileNameCreator.createFileName(msInstance, artifact.getVersion())); + + DeploymentArtifact savedDao = deploymentArtifactGateway.save(artifact); + artifact.setId(savedDao.getId()); + + msInstance.setDeploymentArtifactsInfo(updateMsDeploymentArtifactRef(msInstance.getDeploymentArtifactsInfo(), savedDao.getId())); + msInstanceService.updateMsInstance(msInstance); + + return artifact; + } + + private int updateLatestVersion(DeploymentArtifactsRef ref) { + if(ref == null) return 1; + else return ref.getMostRecentVersion() + 1; + } + + private DeploymentArtifactsRef updateMsDeploymentArtifactRef(DeploymentArtifactsRef ref, String deploymentArtifactId) { + if(ref == null){ + ref = new DeploymentArtifactsRef(); + ref.setMostRecentVersion(1); + List<String> deploymentArtifacts = new ArrayList<>(); + deploymentArtifacts.add(deploymentArtifactId); + ref.setDeploymentArtifacts(deploymentArtifacts); + } + else{ + ref.setMostRecentVersion(ref.getMostRecentVersion() + 1); + List<String> deploymentArtifactList = ref.getDeploymentArtifacts(); + deploymentArtifactList.add(deploymentArtifactId); + } + return ref; + } + + private Map<String, Object> createMetadata(String user) { + Map<String, Object> metadata = new HashMap<>(); + metadata.put("createdOn", new Date()); + metadata.put("createdBy", user); + return metadata; + } + + private Map<String, Object> createSpecificationReferenceInfo(Specification activeSpec) { + Map<String, Object> specInfo = new HashMap<>(); + specInfo.put("id", activeSpec.getId()); + return specInfo; + } + + private MsInstanceInfo createMsInstanceReferenceInfo(MsInstance msInstance) { + MsInstanceInfo msInstanceInfo = new MsInstanceInfo(); + msInstanceInfo.setId(msInstance.getId()); + msInstanceInfo.setName(msInstance.getName()); + msInstanceInfo.setRelease(msInstance.getRelease()); + return msInstanceInfo; + } +} @@ -0,0 +1,77 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.StatusChangeNotValidException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * A class responsible for handling status changes of Deployment Artifacts + */ +@Component +@Slf4j +public class DeploymentArtifactStatusChangeHandler { + + @Autowired + DeploymentArtifactService deploymentArtifactService; + + /** + * setter + * @param deploymentArtifactService + */ + public void setDeploymentArtifactService(DeploymentArtifactService deploymentArtifactService) { + this.deploymentArtifactService = deploymentArtifactService; + } + + /** + * handles status changes + * @param status + * @param deploymentArtifact + */ + public void handleStatusChange(DeploymentArtifactStatus status, DeploymentArtifact deploymentArtifact) { + String msInstanceId = deploymentArtifact.getMsInstanceInfo().getId(); + List<DeploymentArtifact> artifacts = deploymentArtifactService.findByMsInstanceId(msInstanceId); + if( status == DeploymentArtifactStatus.DEV_COMPLETE){ + for(DeploymentArtifact artifact : artifacts){ + if(artifact.getStatus() == DeploymentArtifactStatus.DEV_COMPLETE){ + log.error("Status change is not allowed."); + throw new StatusChangeNotValidException(createValidationErrorMessage(deploymentArtifact)); + } + } + } + deploymentArtifact.setStatus(status); + log.info("Deployment Artifact's status changed successfully."); + } + + private String createValidationErrorMessage(DeploymentArtifact artifact) { + return String.format( "%s (v%d) for %s - Status change not allowed." + + " Only 1 blueprint can be in the DEV_COMPLETE state. " + + "Change the current DEV_COMPLETE blueprint to NOT_NEEDED or IN_DEV before changing another" + + " to DEV_COMPLETE.", artifact.getMsInstanceInfo().getName(), + artifact.getVersion(), artifact.getMsInstanceInfo().getRelease()); + } +} @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; + +import java.util.List; +import java.util.Optional; + +/** + * An interface to interact with MsInstance persistence + */ +public interface MsInstanceGateway { + + Optional<MsInstance> findByNameAndRelease(String name, String release); + + Optional<MsInstance> findById(String msInstanceId); + + List<MsInstance> findAll(); + + MsInstance save(MsInstance msInstance); +} @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceUpdateRequest; + +import java.util.List; + +/** + * An interface to access MsInstance Services + */ +public interface MsInstanceService { + + List<MsInstance> getAll(); + + MsInstance createMicroserviceInstance(String msName, MsInstanceRequest request); + + MsInstance getMsInstanceById(String id); + + void updateMsInstance(MsInstance msInstance); + + void updateStatusBasedOnDeploymentArtifactsStatuses(String msInstanceId); + + void removeDeploymentArtifactFromMsInstance(DeploymentArtifact deploymentArtifact); + + void updateMicroserviceReference(BaseMicroservice msToBeUpdated); + + MsInstance updateMsInstance(MsInstanceUpdateRequest updateRequest, String msInstanceId); +} @@ -0,0 +1,213 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.exceptions.msinstance.MsInstanceAlreadyExistsException; +import org.onap.dcaegen2.platform.mod.model.exceptions.msinstance.MsInstanceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstanceStatus; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceUpdateRequest; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.MsService; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationService; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * MsInstance Service implementation + */ +@Service +@Setter +@Slf4j +public class MsInstanceServiceImpl implements MsInstanceService { + + @Autowired + private MsInstanceGateway msInstanceRepository; + + @Autowired + private MsService msService; + + @Autowired + private MsInstanceStatusChangeHandler msInstanceStatusChangeHandler; + + @Autowired + private SpecificationService specificationService; + + @Autowired + private DeploymentArtifactService deploymentArtifactService; + + @Override + public List<MsInstance> getAll() { + return msInstanceRepository.findAll(); + } + + @Override + @Transactional + public MsInstance createMicroserviceInstance(String msName, MsInstanceRequest request) { + BaseMicroservice microservice = msService.getMicroserviceByName(msName); + checkIftheCombinationOfNameAndReleaseIsUnique(request.getName(), request.getRelease()); + MsInstance msInstance = new MsInstanceCreator(request, microservice).create(); + MsInstance savedMsInstance = msInstanceRepository.save(msInstance); + msService.saveMsInstanceReferenceToMs(microservice, savedMsInstance); + return savedMsInstance; + } + + private void checkIftheCombinationOfNameAndReleaseIsUnique(String name, String release) { + if (msInstanceRepository.findByNameAndRelease(name, release).isPresent()) + throw new MsInstanceAlreadyExistsException(); + } + + @Override + public MsInstance getMsInstanceById(String id) { + return msInstanceRepository.findById(id).orElseThrow(() -> + new MsInstanceNotFoundException(String.format("Ms Instance with id %s not found", id))); + } + + @Override + public void updateMsInstance(MsInstance msInstance) { + log.info("Saving the msInstance {} to database..", msInstance); + if(msInstance != null) msInstanceRepository.save(msInstance); + } + + @Override + public void updateStatusBasedOnDeploymentArtifactsStatuses(String msInstanceId) { + MsInstance msInstance = getMsInstanceById(msInstanceId); + msInstanceStatusChangeHandler.updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + updateMsInstance(msInstance); + } + + @Override + @Transactional + public void removeDeploymentArtifactFromMsInstance(DeploymentArtifact deploymentArtifact) { + MsInstance msInstance = getMsInstanceById(deploymentArtifact.getMsInstanceInfo().getId()); + removeDeploymentArtifactReferenceFromMsInstance(msInstance, deploymentArtifact.getId()); + msInstanceStatusChangeHandler.updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + updateMsInstance(msInstance); + } + + @Override + //TODO: update msInstanceReference in specification and deployment artifact + public void updateMicroserviceReference(BaseMicroservice microservice) { + List<Map<String, String>> msInstanceRefs = microservice.getMsInstances(); + for(Map<String, String> ref : msInstanceRefs){ + MsInstance msInstance = getMsInstanceById(ref.get("id")); + msInstance.setName(microservice.getName()); + msInstance.getMsInfo().put("name", microservice.getName()); + cascadeUpdates(msInstance); + msInstanceRepository.save(msInstance); + } + } + + @Override + @Transactional + public MsInstance updateMsInstance(MsInstanceUpdateRequest updateRequest, String msInstanceId) { + MsInstance msInstance = getMsInstanceById(msInstanceId); + updateRelease(updateRequest, msInstance); + updateVersion(updateRequest, msInstance); + updateMetadata(updateRequest, msInstance); + cascadeUpdates(msInstance); + return msInstanceRepository.save(msInstance); + } + + private void cascadeUpdates(MsInstance msInstance) { + specificationService.updateMsInstanceRef(msInstance); + deploymentArtifactService.updateMsInstanceRef(msInstance); + msService.updateMsInstanceRef(msInstance); + } + + private void updateMetadata(MsInstanceUpdateRequest updateRequest, MsInstance msInstance) { + if(updateRequest.getMetadata() != null){ + msInstance.getMetadata().putAll(updateRequest.getMetadata()); + } + + msInstance.getMetadata().put("updatedOn", new Date()); + msInstance.getMetadata().put("updatedBy", updateRequest.getUser()); + } + + private void updateVersion(MsInstanceUpdateRequest updateRequest, MsInstance msInstance) { + if(updateRequest.getVersion() != null){ + msInstance.setVersion(updateRequest.getVersion()); + } + } + + private void updateRelease(MsInstanceUpdateRequest updateRequest, MsInstance msInstance) { + if(updateRequest.getRelease() != null) { + if(!updateRequest.getRelease().equals(msInstance.getRelease())) + checkIftheCombinationOfNameAndReleaseIsUnique(msInstance.getName(), updateRequest.getRelease()); + msInstance.setRelease(updateRequest.getRelease()); + } + } + + private void removeDeploymentArtifactReferenceFromMsInstance(MsInstance msInstance, String deploymentArtifactId) { + if(msInstance.getDeploymentArtifactsInfo() != null){ + List<String> refIds = msInstance.getDeploymentArtifactsInfo().getDeploymentArtifacts(); + refIds.remove(deploymentArtifactId); + } + } + + private class MsInstanceCreator { + private MsInstanceRequest request; + private BaseMicroservice microserviceDAO; + + MsInstanceCreator(MsInstanceRequest request, BaseMicroservice microserviceDAO) { + this.request = request; + this.microserviceDAO = microserviceDAO; + } + + MsInstance create() { + //prepare MsInstance from the request + return MsInstance.builder() + .name(request.getName()) + .release(request.getRelease()) + .status(MsInstanceStatus.NEW) + .version(request.getVersion()) + .msInfo(getMsReference(microserviceDAO)) + .metadata(getMetadata(request)) + .build(); + } + + private Map<String, Object> getMsReference(BaseMicroservice microserviceDAO) { + Map<String,Object> msInfo = new HashMap<>(); + msInfo.put("id", microserviceDAO.getId()); + msInfo.put("name", microserviceDAO.getName()); + msInfo.put("tag", microserviceDAO.getTag()); + return msInfo; + } + + private Map<String, Object> getMetadata(MsInstanceRequest request) { + Map<String, Object> metadata = request.getMetadata(); + metadata.put("createdBy", request.getUser()); + metadata.put("createdOn", new Date()); + return metadata; + } + } +} @@ -0,0 +1,75 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.microserviceinstance; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstanceStatus; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * A class responsible for handling status changes of Ms Instances + */ +@Component +@Slf4j +public class MsInstanceStatusChangeHandler { + + @Autowired + private MsInstanceService msInstanceService; + + @Autowired + private DeploymentArtifactService deploymentArtifactService; + + public void setMsInstanceService(MsInstanceService msInstanceService) { + this.msInstanceService = msInstanceService; + } + + public void setDeploymentArtifactService(DeploymentArtifactService deploymentArtifactService) { + this.deploymentArtifactService = deploymentArtifactService; + } + + public void updateStatusBasedOnDeploymentArtifactsStatuses(MsInstance msInstance) { + log.info("Checking if any Status change required for msInstance {}...", msInstance); + List<DeploymentArtifact> artifacts = deploymentArtifactService.findByMsInstanceId(msInstance.getId()); + MsInstanceStatus newStatus = getValidStatusBasedOnArtifacts(artifacts); + msInstance.setStatus(newStatus); + log.info("Changed Status to {}", newStatus); + } + + private MsInstanceStatus getValidStatusBasedOnArtifacts(List<DeploymentArtifact> artifacts) { + if(atLeastOneArtifactHasDevCompleteStatus(artifacts)){ + return MsInstanceStatus.DEV_COMPLETE; + } + return MsInstanceStatus.IN_DEV; + } + + private boolean atLeastOneArtifactHasDevCompleteStatus(List<DeploymentArtifact> artifacts) { + return artifacts + .stream() + .anyMatch(artifact -> artifact.getStatus() == DeploymentArtifactStatus.DEV_COMPLETE); + } +} @@ -0,0 +1,37 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.specification; + +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * An interface to interact with Specification persistence + */ +@Repository +public interface SpecificationGateway{ + + List<Specification> getSpecificationByMsInstanceId(String id); + + Specification save(Specification newSpec); +} @@ -0,0 +1,40 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.specification; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; + +import java.util.List; + +/** + * An interface to access Specification Services + */ +public interface SpecificationService { + + List<Specification> getAllSpecsByMsInstanceId(String id); + + Specification createSpecification(String msInstanceId, SpecificationRequest request); + + void updateMsInstanceRef(MsInstance msInstance); +} + @@ -0,0 +1,138 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.specification; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstanceStatus; +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.model.specification.SpecificationStatus; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import lombok.Setter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Specification Service implementation + */ +@Service +@Setter +public class SpecificationServiceImpl implements SpecificationService { + + @Autowired + private SpecificationGateway specificationGateway; + + @Autowired + private MsInstanceService msInstanceService; + + @Autowired + private SpecificationValidatorService specificationValidatorService; + + /** + * Lists all Ms Instances + * @param id + * @return + */ + @Override + public List<Specification> getAllSpecsByMsInstanceId(String id) { + return specificationGateway.getSpecificationByMsInstanceId(id); + } + + /** + * creates a Specification + * @param msInstanceId + * @param request + * @return + */ + @Override + @Transactional + public Specification createSpecification(String msInstanceId, SpecificationRequest request) { + MsInstance msInstance = msInstanceService.getMsInstanceById(msInstanceId); + specificationValidatorService.validateSpecForRelease(request, msInstance.getRelease()); + Specification newSpec = createSpecification(request, msInstance); + makePreviousSpecInactive(msInstance); + Specification savedSpec = specificationGateway.save(newSpec); + updateMsInstance(msInstance, savedSpec); + return savedSpec; + } + + private Specification createSpecification(SpecificationRequest request, MsInstance msInstance) { + return Specification.builder() + .status(SpecificationStatus.ACTIVE) + .specContent(request.getSpecContent()) + .policyJson(request.getPolicyJson()) + .type(request.getType()) + .metadata(getMetadata(request)) + .msInstanceInfo(buildMsInstanceInfo(msInstance)) + .build(); + } + + private void updateMsInstance(MsInstance msInstance, Specification savedSpecification) { + msInstance.setActiveSpec(savedSpecification); + msInstance.setStatus(MsInstanceStatus.IN_DEV); + msInstanceService.updateMsInstance(msInstance); + } + + private void makePreviousSpecInactive(MsInstance msInstance) { + if (msInstance.getActiveSpec() != null) { + msInstance.getActiveSpec().setStatus(SpecificationStatus.INACTIVE); + specificationGateway.save(msInstance.getActiveSpec()); + } + } + + private Map<String, Object> getMetadata(SpecificationRequest request) { + Map<String, Object> metadata = request.getMetadata(); + metadata.put("createdBy", request.getUser()); + metadata.put("createdOn", new Date()); + return metadata; + } + + private Map<String, Object> buildMsInstanceInfo(MsInstance msInstance) { + Map<String, Object> msInstanceInfo = new HashMap<>(); + msInstanceInfo.put("id", msInstance.getId()); + msInstanceInfo.put("name", msInstance.getName()); + msInstanceInfo.put("release", msInstance.getRelease()); + return msInstanceInfo; + } + + /** + * Updates a MsInstance reference in a Specification record + * @param msInstance + */ + @Override + @Transactional + public void updateMsInstanceRef(MsInstance msInstance) { + List<Specification> specifications = getAllSpecsByMsInstanceId(msInstance.getId()); + specifications.forEach((specification) ->{ + specification.getMsInstanceInfo().put("name", msInstance.getName()); + specification.getMsInstanceInfo().put("release", msInstance.getRelease()); + specificationGateway.save(specification); + }); + } + + +} @@ -0,0 +1,30 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.specification; + +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; + +/** + * Abstraction for Specification Validation. + */ +public interface SpecificationValidationStratergy { + public void validate(SpecificationRequest specificationRequest, String release); +} @@ -0,0 +1,61 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.specification; + +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * A service to validate specification + */ +@Service +public class SpecificationValidatorService { + + @Autowired + SpecificationValidationStratergy specValidator; + + public void validateSpecForRelease(SpecificationRequest specificationRequest, String release) { + specValidator.validate(specificationRequest, release); + } +} + + + + + + + + + + + + + + + + + + + + + + @@ -0,0 +1,24 @@ +# +# ============LICENSE_START======================================================= +# org.onap.dcae +# ================================================================================ +# Copyright (c) 2020 AT&T Intellectual Property. 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========================================================= +# + +#add connection to mongo db once its up and running +spring.data.mongodb.host=mongo_db +spring.data.mongodb.port=27017 +spring.data.mongodb.database=dcae_mod
\ No newline at end of file @@ -0,0 +1,131 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.objectmothers; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsLocation; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsStatus; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsType; +import org.onap.dcaegen2.platform.mod.model.common.AuditFields; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.*; + +public class BaseMsObjectMother { + + public static final String BASE_MS_NAME = "ms-1"; + public static final String BASE_MS_ID = "id123"; + public static final BaseMsType BASE_MS_TYPE = BaseMsType.TICK; + public static final BaseMsLocation LOCATION = BaseMsLocation.CENTRAL; + public static final String NAMESPACE = "sam.collector.namespace"; + public static final String NOTE = "Sample Note"; + public static final String LABEL_1 = "mylabel1"; + public static final String LABEL_2 = "mylabel2"; + public static final String USER = "abc123"; + private static final String BASE_MS_TAG = "sample-ms-tag" ; + private static final String BASE_MS_SERVICE_NAME = "sample-core"; + + + public static MicroserviceCreateRequest createMockMsRequest() { + Map<String, Object> metadata = new HashMap(); + metadata.put("notes", NOTE); + metadata.put("labels", Arrays.asList(LABEL_1, LABEL_2)); + + MicroserviceCreateRequest request = new MicroserviceCreateRequest(); + request.setName(BASE_MS_NAME); + request.setTag(BASE_MS_TAG); + request.setServiceName(BASE_MS_SERVICE_NAME); + request.setType(BASE_MS_TYPE); + request.setLocation(LOCATION); + request.setNamespace(NAMESPACE); + request.setMetadata(metadata); + request.setUser(USER); + + return request; + } + + public static BaseMicroservice createMockMsObject() { + BaseMicroservice microservice = new BaseMicroservice(); + microservice.setId(BASE_MS_ID); + microservice.setName(BASE_MS_NAME); + microservice.setServiceName(BASE_MS_SERVICE_NAME); + microservice.setTag(BASE_MS_TAG); + microservice.setType(BASE_MS_TYPE); + microservice.setLocation(LOCATION); + microservice.setNamespace(NAMESPACE); + microservice.setStatus(BaseMsStatus.ACTIVE); + microservice.setMetadata(prepareAuditFields()); + microservice.setMsInstances(createMsInstanceReferences()); + return microservice; + } + + private static List<Map<String, String>> createMsInstanceReferences() { + List<Map<String, String>> msInstanceRefs = new ArrayList<>(); + Map<String, String> msInstance_1 = new HashMap<>(); + msInstance_1.put("name", BASE_MS_NAME); + msInstance_1.put("id", "instance-1"); + Map<String, String> msInstance_2 = new HashMap<>(); + msInstance_2.put("name", BASE_MS_NAME); + msInstance_2.put("id", "instance-2"); + msInstanceRefs.add(msInstance_1); + msInstanceRefs.add(msInstance_2); + return msInstanceRefs; + } + + + public static AuditFields prepareAuditFields() { + return AuditFields.builder() + .createdBy(USER) // prepared by core + .createdOn(new Date(12323132L)) + .updatedBy(USER) + .updatedOn(new Date(12323133L)) + .notes(NOTE) + .labels(Arrays.asList(LABEL_1, LABEL_2)) + .build(); + + } + + public static MicroserviceUpdateRequest createUpdateMsRequest() { + MicroserviceUpdateRequest updateRequest = new MicroserviceUpdateRequest(); + updateRequest.setName("updatedName"); + updateRequest.setLocation(BaseMsLocation.EDGE); + updateRequest.setServiceName("updated-core-name"); + updateRequest.setNamespace("updatedNameSpace"); + updateRequest.setType(BaseMsType.ANALYTIC); + updateRequest.setUser("updater"); + + Map<String, Object> metadata = new HashMap(); + metadata.put("notes", "updatedNote"); + metadata.put("labels", Arrays.asList("updatedLabel1", "updatedLabel2")); + updateRequest.setMetadata(metadata); + return updateRequest; + } + + public static String asJsonString(final Object object) { + try { + return new ObjectMapper().writeValueAsString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} @@ -0,0 +1,222 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.objectmothers; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.MsInstanceInfo; + +import java.util.*; + +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.USER; + +public class DeploymentArtifactObjectMother { + + + public static final String BLUEPRINT_FILENAME = "hello-world-k8s-blueprint.yaml"; + public static final String BLUEPRINT_CONTENT = "\\n#Basic java app to print out at&t buzzwords\\n#1.0" + + ".0\\n#\\n---\\" + "ntosca_definitions_version: cloudify_dsl_1_3\\nimports:\\n- http://www.getcloudify" + + ".org/spec/cloudify/4.4/types" + ".yaml\\n- http://dockercentral.it.att" + + ".com:8093/nexus/repository/rawcentral/com.att.dcae.controller/type_files/" + "k8splugin/1.7.4/node-type" + + ".yaml\\n- http://dockercentral.it.att.com:8093/nexus/repository/rawcentral/com.att.d" + "cae.controller" + + "/type_files/relationship/2006001.1.0/types.yaml\\n- http://dockercentral.it.att.com:8093/nexus/" + + "repository/rawcentral/com.att.dcae.controller/type_files/cloudifydmaapplugin/1.4.10/node-type.yaml\\n- " + + "http:/" + "/dockercentral.it.att.com:8093/nexus/repository/rawcentral/com.att.dcae" + + ".controller/type_files/dcaepolicyplugi" + "n/2.3.3/node-type.yaml\\n- http://dockercentral.it.att" + + ".com:8093/nexus/repository/rawcentral/com.att.dcae.cont" + "roller/type_files/pgaas/0.3.2/pgaas_types" + + ".yaml\\ninputs:\\n ConsulTest1:\\n type: string\\n description" + ": test description\\n " + + "default: 'TEST1'\\n ConsulTest2:\\n type: string\\n description: test description\\n default: " + + "'TEST2'\\n aaf_cert_directory:\\n type: string\\n default: '/opt/app/aafcertman'\\n " + + "description: directory location for the aaf-tls certs\\n additionalsans:\\n type: string\\n " + + "default: ''\\n description: additional sans (string)\\n annotations:\\n default: {}\\n " + + "app_name:\\n type: string\\n default: 'dcae'\\n description: This is used to generateForRelease different" + + " secret code for DCAE or D2A based\\n on Tosca or Helm based BP\\n dcae_service_location:\\n " + + "type: string\\n description: Docker host override for docker bps (string)\\n " + + "dti_sidecar_cpu_limit:\\n type: string\\n default: '250m'\\n description: cpu limit for " + + "deployment (string)\\n dti_sidecar_cpu_request:\\n type: string\\n default: '250m'\\n " + + "description: cpu requested for deployment (string)\\n dti_sidecar_image:\\n type: string\\n " + + "default: 'dockercentral.it.att.com:5100/com.att.dcae.controller/dcae-controller-sidecar:19.11-001'\\n " + + " description: dti side car image for dti (string)\\n dti_sidecar_memory_limit:\\n type: string\\n " + + " default: '128Mi'\\n description: memory limit for deployment (string)\\n " + + "dti_sidecar_memory_request:\\n type: string\\n default: '128Mi'\\n description: memory " + + "requested for deployment (string)\\n dti_sidecar_port:\\n type: string\\n default: ''\\n " + + "description: Port for the side car (string)\\n hello-buzzword_cpu_limit:\\n type: string\\n " + + "default: '250m'\\n description: cpu limit for deployment (string)\\n hello-buzzword_cpu_request:\\n " + + " type: string\\n default: '250m'\\n description: cpu requested for deployment (string)\\n " + + "hello-buzzword_memory_limit:\\n type: string\\n default: '128Mi'\\n description: memory limit " + + "for deployment (string)\\n hello-buzzword_memory_request:\\n type: string\\n default: '128Mi'\\n " + + " description: memory requested for deployment (string)\\n idns_fqdn:\\n type: string\\n " + + "default: ''\\n description: The idns you will be using for your deployment (string)\\n image:\\n " + + "type: string\\n default: 'test-image-uri'\\n description: The docker image for your microservice " + + "(string)\\n namespace:\\n type: string\\n replicas:\\n type: integer\\n default: 1\\n " + + "description: The number of replicas for your kubernetes deployment (integer)\\n " + + "service_component_name_override:\\n type: string\\n default: 'hello-buzzword'\\n description: " + + "Unique identifier for your deployment (string)\\n use_aaf_tls:\\n type: boolean\\n default: " + + "false\\n description: To use or not use the aaf section (boolean)\\n use_dti_info:\\n type: " + + "boolean\\n default: true\\n description: Flag to use or not use dti (boolean)\\nnode_templates:\\n" + + " hello-buzzword_hello-buzzword:\\n type: dcae.nodes.ContainerizedServiceComponent\\n " + + "properties:\\n application_config:\\n services_calls: []\\n streams_publishes: {}\\n " + + " streams_subscribes: {}\\n ConsulTest1:\\n get_input: ConsulTest1\\n " + + "ConsulTest2:\\n get_input: ConsulTest2\\n docker_config:\\n healthcheck:\\n " + + " interval: 180s\\n timeout: 30s\\n script: \\\"true\\\"\\n type: docker\\n " + + " livehealthcheck:\\n interval: 180s\\n timeout: 30s\\n script: " + + "\\\"true\\\"\\n type: docker\\n reconfigs:\\n dti: dti/test-script\\n " + + "app_reconfig: /app-reconfig/test-script\\n env:\\n - name: DTI_DATA_DIR\\n value:" + + " /dtidata\\n - name: KUBE_CLUSTER_FQDN\\n value: {get_secret: " + + "kc-kubernetes_master_ip}\\n image:\\n get_input: image\\n location_id:\\n " + + "get_input: dcae_service_location\\n service_component_type: hello-buzzword\\n replicas:\\n " + + " get_input: replicas\\n service_component_name_override:\\n concat:\\n - " + + "get_secret: location_id\\n - '-'\\n - get_input: service_component_name_override\\n " + + "k8s_controller_type: statefulset\\n configuration:\\n file_content:\\n apiVersion: " + + "v1\\n clusters:\\n - name: default-cluster\\n cluster:\\n " + + "server:\\n concat:\\n - https://\\n - get_secret: " + + "kc-kubernetes_master_ip\\n - ':'\\n - get_secret: " + + "kc-kubernetes_master_port\\n insecure-skip-tls-verify: true\\n contexts:\\n " + + " - name: default-context\\n context:\\n cluster: default-cluster\\n " + + " namespace:\\n get_input: namespace\\n user: default-user\\n " + + "kind: Config\\n preferences: {}\\n users:\\n - name: default-user\\n " + + " user:\\n token:\\n get_secret:\\n concat:\\n " + + " - get_input: app_name\\n - -mechid-k8s-token\\n current-context: " + + "default-context\\n resource_config:\\n limits:\\n cpu:\\n get_input: " + + "hello-buzzword_cpu_limit\\n memory:\\n get_input: hello-buzzword_memory_limit\\n " + + " requests:\\n cpu:\\n get_input: hello-buzzword_cpu_request\\n " + + "memory:\\n get_input: hello-buzzword_memory_request\\n aaf_tls_info:\\n " + + "use_aaf_tls:\\n get_input: use_aaf_tls\\n cert_directory:\\n get_input: " + + "aaf_cert_directory\\n image: dockercentral.it.att.com:5100/com.att.ecompcntr" + + ".public/ecompc-aaf-init-container:1.0.2\\n env:\\n - name: NAMESPACE\\n " + + "valueFrom:\\n fieldRef:\\n fieldPath: metadata.namespace\\n - name: " + + "deployer_id\\n valueFrom:\\n secretKeyRef:\\n name:\\n " + + "concat:\\n - get_input: namespace\\n - -cert-secret\\n key: " + + "deployerid\\n - name: deployer_pass\\n valueFrom:\\n secretKeyRef:\\n " + + " name:\\n concat:\\n - get_input: namespace\\n - " + + "-cert-secret\\n key: deployerpass\\n - name: cert_id\\n valueFrom:\\n " + + " secretKeyRef:\\n name:\\n concat:\\n - get_input: " + + "namespace\\n - -cert-secret\\n key: certid\\n - name: cm_url\\n " + + " valueFrom:\\n secretKeyRef:\\n name:\\n concat:\\n " + + " - get_input: namespace\\n - -cert-secret\\n key: cmurl\\n - " + + "name: idns_fqdn\\n value:\\n get_input: idns_fqdn\\n - name: " + + "app_service_names\\n value:\\n concat:\\n - get_secret: location_id\\n " + + " - '-'\\n - get_input: service_component_name_override\\n args:\\n - " + + "place\\n - cmtemplate\\n - -idnsfqdn=$(idns_fqdn)\\n - -cmurl=$(cm_url)\\n -" + + " -deployerid=$(deployer_id)\\n - -deployerpass=$(deployer_pass)\\n - -certid=$(cert_id)\\n" + + " - -namespace=$(NAMESPACE)\\n - -services=$(app_service_names)\\n - concat:\\n " + + " - -additionalsans=\\n - get_input: additionalsans\\n use_aaf_tls_renewal: true\\n " + + " renewal_args:\\n - renew\\n - -idnsfqdn=$(idns_fqdn)\\n - -cmurl=$(cm_url)\\n" + + " resource_config:\\n limits:\\n cpu: 250m\\n memory: 256Mi\\n " + + " requests:\\n cpu: 100m\\n memory: 256Mi\\n annotations:\\n " + + "get_input: annotations\\n dti_info:\\n image:\\n get_input: dti_sidecar_image\\n " + + " use_dti_info:\\n get_input: use_dti_info\\n healthcheck:\\n interval: " + + "90s\\n timeout: 60s\\n type: https\\n endpoint: /healthcheck\\n " + + "livehealthcheck:\\n interval: 90s\\n timeout: 60s\\n type: https\\n " + + "endpoint: /healthcheck\\n dtidata_directory: /dtidata\\n resource_config:\\n " + + "limits:\\n cpu:\\n get_input: dti_sidecar_cpu_limit\\n memory:\\n " + + " get_input: dti_sidecar_memory_limit\\n requests:\\n cpu:\\n " + + "get_input: dti_sidecar_cpu_request\\n memory:\\n get_input: " + + "dti_sidecar_memory_request\\n env:\\n - name: DTI_DATA_DIR\\n value: /dtidata\\n " + + " - name: KUBE_CLUSTER_FQDN\\n value: {get_secret: kc-kubernetes_master_ip}\\n - " + + "name: KUBE_PROXY_FQDN\\n value: {get_secret: kube_proxy_fqdn}\\n - name: POD_SVC_PORT\\n" + + " value: '9999'\\n ports:\\n - concat:\\n - '9999:'\\n - " + + "get_input: dti_sidecar_port\\n relationships: []"; + + public static final String SPEC_FILE_AS_STRING = String.format("{\r\n\t\"self\": {\r\n\t\t\"component_type\": " + + "\"docker\",\r\n\t\t\"description\": \"Basic java app to print out at&t buzzwords\",\r\n\t\t\"name\": " + + "\"hello-buzzword\",\r\n\t\t\"version\": \"1.0.0\"\r\n\t},\r\n\t\r\n\t\"services\": {\r\n\t\t\"calls\": " + + "[],\r\n\t\t\"provides\": []\r\n\t},\r\n\t\"streams\": {\r\n\t\t\"publishes\": [],\r\n\t\t\"subscribes\":" + + " []\r\n\t},\r\n\t\"parameters\": [\r\n\t\t{\r\n \"name\": \"ConsulTest1\",\r\n " + + "\"value\": \"TEST1\",\r\n \"description\": \"Test consul output\"," + + "\r\n\t\t\t\"sourced_at_deployment\": true,\r\n\t\t\t\"designer_editable\": true," + + "\r\n\t\t\t\"policy_editable\": false,\r\n\t\t\t\"type\": \"string\" ,\r\n\t\t\t\"description\": \"test " + + "description\" \r\n },\r\n {\r\n \"name\": \"ConsulTest2\",\r\n " + + " \"value\": \"TEST2\",\r\n\t\t\t\"sourced_at_deployment\": true,\r\n\t\t\t\"designer_editable\": true," + + "\r\n\t\t\t\"policy_editable\": false,\r\n\t\t\t\"type\": \"string\",\r\n\t\t\t\"description\": \"test " + + "description\" \r\n }\r\n \r\n\t],\r\n\r\n\t\"auxilary\": {\r\n\t\t\"healthcheck\": " + + "{\r\n\t\t\t\"type\": \"docker\",\r\n \t\"script\": \"true\",\r\n \t\"timeout\": \"30s\"," + + "\r\n \t\"interval\": \"180s\"\r\n\t\t},\r\n\t\t\"livehealthcheck\": {\r\n\t\t\t\"type\": " + + "\"docker\",\r\n \t\"script\": \"true\",\r\n \t\"timeout\": \"30s\",\r\n " + + "\t\"interval\": \"180s\"\r\n\t\t},\r\n\t\t\"reconfigs\": {\r\n\t\t\t\"app_reconfig\" : " + + "\"/app-reconfig/test-script\",\r\n\t\t\t\"dti\" : \"dti/test-script\"}}," + + "\r\n\t\"artifacts\": [{\r\n\t\t\"type\": \"docker image\",\r\n\t\t\"uri\": " + + "\"test-image-uri\"\r\n\t}]\r\n}"); + + public static DeploymentArtifact createDeploymentArtifactDAO(DeploymentArtifactStatus status) { + DeploymentArtifact artifact = new DeploymentArtifact(); + artifact.setId("id-123"); + artifact.setFileName("helloworld-k8s-blueprint.yaml"); + artifact.setContent("some " + "yaml content"); + artifact.setStatus(status); + artifact.setVersion(1); + artifact.setMetadata(createMetaData()); + artifact.setMsInstanceInfo(createMsInstanceInfo()); + artifact.setSpecificationInfo(createSpecificationInfo()); + + return artifact; + } + + private static Map<String, Object> createSpecificationInfo() { + Map<String, Object> msInstanceInfo = new HashMap<>(); + msInstanceInfo.put("id", "id-123"); + return msInstanceInfo; + } + + private static MsInstanceInfo createMsInstanceInfo() { + MsInstanceInfo msInstanceInfo = new MsInstanceInfo(); + msInstanceInfo.setId(MsInstanceObjectMother.MS_INSTANCE_ID); + msInstanceInfo.setName(MsInstanceObjectMother.MS_INSTANCE_NAME); + msInstanceInfo.setRelease(MsInstanceObjectMother.RELEASE); + return msInstanceInfo; + } + + private static Map<String, Object> createMetaData() { + Map<String, Object> metadata = new HashMap<>(); + metadata.put("createdBy", USER); + metadata.put("createdOn", "someDate"); + metadata.put("notes", "This is a test Deployment Artifact"); + metadata.put("labels", Arrays.asList("hello", "world")); + return metadata; + } + + public static Map<String, Object> createBlueprintResponse() { + Map<String, Object> blueprintMap = new HashMap<>(); + blueprintMap.put("fileName", BLUEPRINT_FILENAME); + blueprintMap.put("content", BLUEPRINT_CONTENT); return blueprintMap; + } + + public static Map<String, Object> createToolboxBlueprintResponse() { + Map<String, Object> blueprintResponseMap = new HashMap<>(); + blueprintResponseMap.put("blueprint_name", "hello-buzzword-eom-k8s"); + blueprintResponseMap.put("blueprint_content", BLUEPRINT_CONTENT); + blueprintResponseMap.put("componentSpecValidated", true); + return blueprintResponseMap; + } + + public static List<DeploymentArtifact> createMockDeploymentArtifactsWithDifferentStatuses + (boolean devCompleteRequire) { + DeploymentArtifact d1; + if(devCompleteRequire){ + d1 = createDeploymentArtifactDAO(DeploymentArtifactStatus.DEV_COMPLETE); + }else { + d1 = createDeploymentArtifactDAO(DeploymentArtifactStatus.NOT_NEEDED); + } + DeploymentArtifact d2 = createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + return new ArrayList<>(Arrays.asList(d1, d2)); + } + +} @@ -0,0 +1,112 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.objectmothers; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.DeploymentArtifactsRef; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstanceStatus; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +public class MsInstanceObjectMother { + + public static final String MS_INSTANCE_NAME = "ms-instance-1"; + public static final String MS_INSTANCE_ID = "id-123"; + public static final String RELEASE = "2002"; + public static final String VERSION = "1.1"; + public static final String USER = "user-1"; + public static final String BASE_MS_TAG = "ms-instance-1-tag"; + public static final String SCRUMLEAD = "Sam"; + public static final String SYSTEMSENGINEER = "John"; + + public static MsInstanceRequest getMsInstanceMockRequest() { + Map<String, Object> metadataFromRequest = buildMockMetadataForRequest(); + + MsInstanceRequest request = MsInstanceRequest.builder() + .name(MS_INSTANCE_NAME) + .release(RELEASE) + .version(VERSION) + .user(USER) + .metadata(metadataFromRequest) + .build(); + + return request; + } + + private static Map<String, Object> buildMockMetadataForRequest() { + Map<String, Object> metadataFromRequest = new HashMap<>(); + metadataFromRequest.put("pstDueDate", "14-04-2020"); + metadataFromRequest.put("pstDueIteration", "1.2"); + metadataFromRequest.put("eteDueDate", "21-05-2020"); + metadataFromRequest.put("eteDueIteration", "1.3"); + metadataFromRequest.put("scrumLead", SCRUMLEAD); + metadataFromRequest.put("systemsEngineer", SYSTEMSENGINEER); + return metadataFromRequest; + } + + + public static MsInstance createMsInstance() { + Map<String, Object> metadataFromResponse = buildMockMetadataForRequest().entrySet() + .stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + metadataFromResponse.put("createdOn", "currentDate"); + metadataFromResponse.put("createdBy", USER); + metadataFromResponse.put("scrumLead", SCRUMLEAD); + metadataFromResponse.put("systemsEngineer", SYSTEMSENGINEER); + + Map<String, Object> msInfo = new HashMap<>(); + msInfo.put("id", BaseMsObjectMother.BASE_MS_ID); + msInfo.put("name", BaseMsObjectMother.BASE_MS_NAME); + msInfo.put("tag", BASE_MS_TAG); + + MsInstance msInstance = MsInstance.builder() + .id(MS_INSTANCE_ID) + .name(MS_INSTANCE_NAME) + .release(RELEASE) + .version(VERSION) + .status(MsInstanceStatus.NEW) + .metadata(metadataFromResponse) + .msInfo(msInfo) + .activeSpec(SpecificationObjectMother.getMockSpecification(DeploymentType.DOCKER)) + .build(); + + return msInstance; + } + + public static MsInstance getMsInstanceWithExistingDeploymentArtifactRef() { + MsInstance msInstance = createMsInstance(); + + DeploymentArtifactsRef deploymentArtifactRef = new DeploymentArtifactsRef(); + deploymentArtifactRef.setMostRecentVersion(1); + + ArrayList<String> deploymentArtifactList = new ArrayList<>(); + deploymentArtifactList.add("id-456"); + deploymentArtifactRef.setDeploymentArtifacts(deploymentArtifactList); + + msInstance.setDeploymentArtifactsInfo(deploymentArtifactRef); + + return msInstance; + } +} @@ -0,0 +1,41 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.objectmothers; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.util.TestUtil; + +public class SpecificationObjectMother { + public static final String SPEC_REQUEST = "src/test/resources/http/requests/CreateSpecificationRequest.json"; + public static final String SPEC_RESPONSE = "src/test/resources/http/requests/CreateSpecificationResponse.json"; + + public static SpecificationRequest getSpecificationRequest() { + return TestUtil.deserializeJsonFileToModel(SPEC_REQUEST, SpecificationRequest.class); + } + + public static Specification getMockSpecification(DeploymentType type) { + Specification specification = TestUtil.deserializeJsonFileToModel(SPEC_RESPONSE, Specification.class); + specification.setType(type); + return specification; + } +} @@ -0,0 +1,147 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.persistence; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactFilter; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactSearch; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.mongo.deploymentartifact.DeploymentArtifactMongoGateway; +import org.onap.dcaegen2.platform.mod.mongo.deploymentartifact.DeploymentArtifactMongoRepo; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactGateway; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Arrays; +import java.util.List; + +@Disabled("Embedded mongodb jar is not available in the maven repo.") +@SpringBootTest +@ExtendWith(SpringExtension.class) +public class DeploymentArtifactGatewayTest { + + DeploymentArtifactGateway gateway; + + @Autowired + DeploymentArtifactMongoRepo repo; + + @Autowired + MongoOperations operations; + + @BeforeEach + public void setUp(){ + gateway = new DeploymentArtifactMongoGateway(repo); + + operations.dropCollection(DeploymentArtifact.class); + + String r_2008 = "2008"; + String r_2010 = "2010"; + + DeploymentArtifactStatus inDev = DeploymentArtifactStatus.IN_DEV; + DeploymentArtifactStatus devComplete = DeploymentArtifactStatus.DEV_COMPLETE; + + String tag_1 = "hello-one"; + String tag_2 = "hello-two"; + String tag_3 = "hello-three"; + + DeploymentArtifact artifact_1 = getDeploymentArtifact(r_2008, inDev, tag_1); + DeploymentArtifact artifact_2 = getDeploymentArtifact(r_2010, devComplete, tag_2); + DeploymentArtifact artifact_3 = getDeploymentArtifact(r_2008, devComplete, tag_3); + + operations.insertAll(Arrays.asList(artifact_1, artifact_2, artifact_3)); + operations.findAll(DeploymentArtifact.class).forEach(System.out::println); + + System.out.println(); + } + + private static DeploymentArtifact getDeploymentArtifact(String r_2008, DeploymentArtifactStatus inDev, + String tag) { + DeploymentArtifact artifact_1 = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(inDev); + artifact_1.getMsInstanceInfo().setRelease(r_2008); + //Currently searching tag in filename as it is not present in DeploymentArtifact record + artifact_1.setFileName(tag); + artifact_1.setId(null); + + return artifact_1; + } + + @Test + public void findByOnlyRelease() throws Exception { + DeploymentArtifactSearch search = new DeploymentArtifactSearch(); + DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); + filter.setRelease("2008"); + search.setFilter(filter); + + List<DeploymentArtifact> artifacts = gateway.findAll(search); + Assertions.assertThat(artifacts.size()).isEqualTo(2); + } + + @Test + public void findWithOnlyStatus() throws Exception { + DeploymentArtifactSearch search = new DeploymentArtifactSearch(); + DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); + filter.setStatus(DeploymentArtifactStatus.IN_DEV); + search.setFilter(filter); + + List<DeploymentArtifact> artifacts = gateway.findAll(search); + + Assertions.assertThat(artifacts.size()).isEqualTo(1); + } + + @Test + public void findWithStatusAndRelease() throws Exception { + DeploymentArtifactSearch search = new DeploymentArtifactSearch(); + DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); + filter.setStatus(DeploymentArtifactStatus.DEV_COMPLETE); + filter.setRelease("2008"); + search.setFilter(filter); + + List<DeploymentArtifact> artifacts = gateway.findAll(search); + + Assertions.assertThat(artifacts.size()).isEqualTo(3); + } + + @Test + public void findWithTag() throws Exception { + DeploymentArtifactSearch search = new DeploymentArtifactSearch(); + DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); + filter.setTag("hello-one"); + search.setFilter(filter); + + List<DeploymentArtifact> artifacts = gateway.findAll(search); + + Assertions.assertThat(artifacts.size()).isEqualTo(1); + } + + @Test + public void findWithNoQuery() throws Exception { + List<DeploymentArtifact> artifacts = gateway.findAll(new DeploymentArtifactSearch()); + Assertions.assertThat(artifacts.size()).isEqualTo(0); + } +} @@ -0,0 +1,53 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.util; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +public class TestUtil { + + private static final ObjectMapper MAPPER = new ObjectMapper(); + + private TestUtil() {} + + public static Map<String, Object> readJsonFileAsObjectMap(String filePath) { + try { + return MAPPER.readValue(new File(filePath), new TypeReference<Map<String, Object>>() {}); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(); + } + } + + public static <T> T deserializeJsonFileToModel(String filePath, Class<T> modelClass) { + try { + return MAPPER.readValue(new File(filePath), modelClass); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException(); + } + } +} @@ -0,0 +1,165 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.exceptions.OperationNotAllowedException; +import org.onap.dcaegen2.platform.mod.model.exceptions.ResourceConflictException; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.onap.dcaegen2.platform.mod.web.controller.BaseMicroserviceController; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.MsService; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.Arrays; + +import static org.onap.dcaegen2.platform.mod.model.exceptions.ErrorMessages.MICROSERVICE_NAME_CONFLICT_MESSAGE; + +@ExtendWith(SpringExtension.class) +@WebMvcTest(BaseMicroserviceController.class) +class BaseMicroserviceControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private MsService mockBaseMsService; + + @BeforeEach + void setUp() { + } + + @Test + void test_GetAllBaseMicroservices_returnsListOfDTOs() throws Exception { + //arrange + BaseMicroservice ms1 = new BaseMicroservice(); + ms1.setName("HelloWorld1"); + BaseMicroservice ms2 = new BaseMicroservice(); + ms2.setName("HelloWorld2"); + + Mockito.when(mockBaseMsService.getAllMicroservices()).thenReturn(Arrays.asList(ms1, ms2)); + + //act/assert + mockMvc.perform(MockMvcRequestBuilders.get("/api/base-microservice") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(2))); + } + + @Test + void test_addBaseMicroservice_returnsMicroservice() throws Exception { + //arrange + MicroserviceCreateRequest microserviceRequest = BaseMsObjectMother.createMockMsRequest(); + + //response + BaseMicroservice microserviceDao = BaseMsObjectMother.createMockMsObject(); + + Mockito.when(mockBaseMsService.createMicroservice(microserviceRequest)).thenReturn(microserviceDao); + + //act/assert + mockMvc.perform(MockMvcRequestBuilders.post("/api/base-microservice") + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(microserviceRequest)) + .characterEncoding("utf-8")) + .andExpect(MockMvcResultMatchers.status().isCreated()) + .andExpect((MockMvcResultMatchers.jsonPath("$.id", Matchers.equalTo(BaseMsObjectMother.BASE_MS_ID)))) + .andExpect(MockMvcResultMatchers.jsonPath("$.name", Matchers.equalTo(BaseMsObjectMother.BASE_MS_NAME))) + .andExpect(MockMvcResultMatchers.jsonPath("$.metadata.createdBy", Matchers.equalTo(BaseMsObjectMother.USER))); + } + + @Test + void test_addBaseMicroserviceWithDuplicateName_shouldThrowConflictError() throws Exception{ + //arrange + MicroserviceCreateRequest microserviceRequest = BaseMsObjectMother.createMockMsRequest(); + Mockito.when(mockBaseMsService.createMicroservice(ArgumentMatchers.any())).thenThrow(new ResourceConflictException(MICROSERVICE_NAME_CONFLICT_MESSAGE)); + + //act/assert + mockMvc.perform(MockMvcRequestBuilders.post("/api/base-microservice") + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(microserviceRequest))) + .andExpect(MockMvcResultMatchers.status().isConflict()); + } + + @Test + void test_updateBaseMicroserviceEndpoint() throws Exception{ + MicroserviceUpdateRequest microserviceRequest = BaseMsObjectMother.createUpdateMsRequest(); + String requestedMsId = "id-123"; + + mockMvc.perform(MockMvcRequestBuilders.patch(String.format(BaseMicroserviceController.API_BASE_MICROSERVICE + "/%s", requestedMsId)) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(microserviceRequest)) + .characterEncoding("utf-8")) + .andExpect(MockMvcResultMatchers.status().isNoContent()); + Mockito.verify(mockBaseMsService, Mockito.times(1)).updateMicroservice(requestedMsId, microserviceRequest); + } + + @Test + void test_OperationNotAllowedExceptionThrows409() throws Exception{ + MicroserviceUpdateRequest microserviceRequest = BaseMsObjectMother.createUpdateMsRequest(); + String requestedMsId = "id-123"; + Mockito.doThrow(new OperationNotAllowedException("")). + when(mockBaseMsService).updateMicroservice(requestedMsId, microserviceRequest); + + mockMvc.perform(MockMvcRequestBuilders.patch(String.format(BaseMicroserviceController.API_BASE_MICROSERVICE + "/%s", requestedMsId)) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(microserviceRequest))) + .andExpect(MockMvcResultMatchers.status().isConflict()); + } + + @Test + void test_validateMsRequestShouldThrowCorrectResponse() throws Exception { + //arrange + MicroserviceCreateRequest microserviceRequest = BaseMsObjectMother.createMockMsRequest(); + microserviceRequest.setName(" "); + microserviceRequest.setTag("123"); + microserviceRequest.setServiceName("123"); + microserviceRequest.setUser(" "); + + //response + BaseMicroservice microserviceDao = BaseMsObjectMother.createMockMsObject(); + + Mockito.when(mockBaseMsService.createMicroservice(microserviceRequest)).thenReturn(microserviceDao); + + //act/assert + mockMvc.perform(MockMvcRequestBuilders.post("/api/base-microservice") + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(microserviceRequest)) + .characterEncoding("utf-8")) + .andExpect(MockMvcResultMatchers.status().isBadRequest()) + .andExpect(MockMvcResultMatchers.jsonPath("$.message", Matchers.equalTo("Validation failed."))) + .andExpect(MockMvcResultMatchers.jsonPath("$.errors", Matchers.hasSize(4))) + ; + } +}
\ No newline at end of file @@ -0,0 +1,170 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.BlueprintFileNameCreateException; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.DeploymentArtifactNotFound; +import org.onap.dcaegen2.platform.mod.model.restapi.DeploymentArtifactPatchRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.controller.DeploymentArtifactController; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.Arrays; +import java.util.List; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; + +@WebMvcTest(DeploymentArtifactController.class) +class DeploymentArtifactControllerTest { + + @Autowired + MockMvc mockMvc; + + @MockBean + DeploymentArtifactService service; + + @BeforeEach + void setUp() { + } + + @Test + void test_GenerateDeploymentArtifactEndpoint_returnsBlueprint() throws Exception{ + String url = String.format("/api/deployment-artifact/%s?user=%s", MsInstanceObjectMother.MS_INSTANCE_ID, MsInstanceObjectMother.USER); + DeploymentArtifact response = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + + Mockito.when(service.generateDeploymentArtifact(MsInstanceObjectMother.MS_INSTANCE_ID, MsInstanceObjectMother.USER)).thenReturn(response); + + mockMvc.perform(post(url)) + .andExpect(MockMvcResultMatchers.status().isCreated()) + .andExpect(MockMvcResultMatchers.jsonPath("$.fileName").exists()) + .andExpect(MockMvcResultMatchers.jsonPath("$.content").exists()); + + Mockito.verify(service, Mockito.times(1)).generateDeploymentArtifact(MsInstanceObjectMother.MS_INSTANCE_ID, MsInstanceObjectMother.USER); + } + + @Test + void test_RaiseExceptionIfBlueprintNameCanNotBeCreated() throws Exception{ + String url = String.format("/api/deployment-artifact/%s?user=%s", MsInstanceObjectMother.MS_INSTANCE_ID, + MsInstanceObjectMother.USER); + DeploymentArtifact response = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + + Mockito.when(service.generateDeploymentArtifact(MsInstanceObjectMother.MS_INSTANCE_ID, MsInstanceObjectMother.USER)).thenThrow(new BlueprintFileNameCreateException("")); + + mockMvc.perform(post(url)) + .andExpect(MockMvcResultMatchers.status().is4xxClientError()); + } + + @Test + void test_GetAllDeploymentArtifactsShouldReturnList() throws Exception{ + List<DeploymentArtifact> daos = createDaos(); + Mockito.when(service.getAllDeploymentArtifacts()).thenReturn(daos); + + mockMvc.perform(get("/api/deployment-artifact")) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(2))); + + } + + private List<DeploymentArtifact> createDaos() { + DeploymentArtifact dao1 = new DeploymentArtifact(); + dao1.setId("123"); + DeploymentArtifact dao2 = new DeploymentArtifact(); + dao2.setId("456"); + + return Arrays.asList(dao1, dao2); + } + + @Test + void test_GetAllDeploymentArtifactTestShouldReturnAList() throws Exception{ + + mockMvc.perform(get(DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL + DeploymentArtifactController.GET_STATUSES)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$", Matchers.hasSize(DeploymentArtifactStatus.values().length))); + } + + @Test + void test_ifUserIsNullRaiseException() throws Exception{ + String id = "id-123"; + String user = ""; + + mockMvc.perform(patch(DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL + "/" + id + "?user=" + user) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(new DeploymentArtifactPatchRequest()))) + .andExpect(MockMvcResultMatchers.status().isBadRequest()); + } + + @Test + void test_ChangeStatusOfDeploymentArtifact() throws Exception{ + + String id = "id-123"; + String user = "user1"; + DeploymentArtifactPatchRequest partialDto = new DeploymentArtifactPatchRequest(); + partialDto.setStatus(DeploymentArtifactStatus.DEV_COMPLETE); + + mockMvc.perform(patch(DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL + "/" + id + "?user=" + user) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(partialDto))) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.message").exists()); + + Mockito.verify(service, Mockito.times(1)).updateDeploymentArtifact(id, partialDto, user); + + } + + @Test + void test_deploymentArtifactIdNotFound() throws Exception{ + String wrongId = "wrong-id"; + DeploymentArtifactPatchRequest partialDto = new DeploymentArtifactPatchRequest(); + partialDto.setStatus(DeploymentArtifactStatus.DEV_COMPLETE); + + Mockito.doThrow(new DeploymentArtifactNotFound("")).when(service). + updateDeploymentArtifact(wrongId, partialDto, "user-1"); + + mockMvc.perform(patch(DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL + "/" + wrongId + "?user=" + "user-1") + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(partialDto))) + .andExpect(MockMvcResultMatchers.status().isBadRequest()); + } + + @Test + void test_deleteDeploymentArtifactEndpoint() throws Exception{ + String deploymentArtifactId = "id-123"; + String user = "user-1"; + mockMvc.perform(delete(DeploymentArtifactController.DEPLOYMENT_ARTIFACTS_BASE_URL + "/" + deploymentArtifactId + "?user=" + user)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.jsonPath("$.message").exists()); + Mockito.verify(service, Mockito.times(1)).deleteDeploymentArtifact(deploymentArtifactId); + } +}
\ No newline at end of file @@ -0,0 +1,145 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceUpdateRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.controller.MicroserviceInstanceController; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.*; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@WebMvcTest(MicroserviceInstanceController.class) +class MicroserviceInstanceControllerTest { + + @MockBean + MsInstanceService service; + + @Autowired + MockMvc mockMvc; + + @BeforeEach + void setUp() { + } + + @Test + void getAll() throws Exception { + MsInstance instance_1 = MsInstance.builder().id("123").build(); + MsInstance instance_2 = MsInstance.builder().id("345").build(); + + when(service.getAll()).thenReturn(Arrays.asList(instance_1,instance_2)); + + mockMvc.perform(get("/api/microservice-instance") + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$",hasSize(2))); + verify(service, times(1)).getAll(); + } + + @Test + void createMsInstance_shouldReturn201AndResponseBody() throws Exception { + + MsInstanceRequest request = getMsInstanceMockRequest(); + MsInstance msInstance = createMsInstance(); + + when(service.createMicroserviceInstance(BaseMsObjectMother.BASE_MS_NAME, request)).thenReturn(msInstance); + + mockMvc.perform(MockMvcRequestBuilders.post("/api/microservice-instance/"+ BaseMsObjectMother.BASE_MS_NAME) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(request)).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isCreated()) + .andExpect(jsonPath("$.name",equalTo(MS_INSTANCE_NAME))); + + verify(service, times(1)).createMicroserviceInstance(BaseMsObjectMother.BASE_MS_NAME,request); + } + + @Test + void patchMsInstance_shouldReturn204NoContent() throws Exception{ + //given + String updatedVersion = "updatedVersion"; + String updatedRelease = "updatedRelease"; + + MsInstance mockedMsInstance = prepareMockMsInstance(updatedVersion, updatedRelease); + String msInstanceId = mockedMsInstance.getId(); + + MsInstanceUpdateRequest updateRequest = prepareMsInstanceUpdateRequest(updatedVersion, updatedRelease); + + when(service.updateMsInstance(updateRequest, msInstanceId)).thenReturn(mockedMsInstance); + + mockMvc.perform(patch("/api/microservice-instance/" + msInstanceId) + .contentType(MediaType.APPLICATION_JSON) + .content(BaseMsObjectMother.asJsonString(updateRequest))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.release", equalTo(updatedRelease))) + .andExpect(jsonPath("$.version", equalTo(updatedVersion))) + .andExpect(jsonPath("$.metadata.scrumLead", equalTo("updatedScrumLead"))); + + verify(service, times(1)).updateMsInstance(updateRequest, msInstanceId); + } + + private MsInstanceUpdateRequest prepareMsInstanceUpdateRequest(String updatedVersion, String updatedRelease) { + MsInstanceUpdateRequest updateRequest = new MsInstanceUpdateRequest(); + updateRequest.setRelease(updatedRelease); + updateRequest.setVersion(updatedVersion); + updateRequest.setMetadata(prepareMetadataToBeUpdated()); + return updateRequest; + } + + private Map<String, Object> prepareMetadataToBeUpdated() { + Map<String, Object> metadata = new HashMap<>(); + metadata.put("scrumLead", "updatedScrumLead"); + return metadata; + } + + private MsInstance prepareMockMsInstance(String updatedVersion, String updatedRelease) { + MsInstance msInstanceToBeUpdated = MsInstanceObjectMother.createMsInstance(); + msInstanceToBeUpdated.setVersion(updatedVersion); + msInstanceToBeUpdated.setRelease(updatedRelease); + msInstanceToBeUpdated.getMetadata().put("scrumLead", "updatedScrumLead"); + return msInstanceToBeUpdated; + } + +}
\ No newline at end of file @@ -0,0 +1,87 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web; + +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import java.util.Set; + +public class MsRequestValidationTest { + + public Validator validator; + private MicroserviceCreateRequest request; + + @BeforeEach + public void setup(){ + validator = Validation.buildDefaultValidatorFactory().getValidator(); + request = BaseMsObjectMother.createMockMsRequest(); + } + + @Test + void test_msNameShouldNotBeBlank(){ + request.setName(" "); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + } + + @Test + void test_msTagShouldNotBeNull(){ + request.setTag(null); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + + } + + @Test + void test_msTagShouldFollowRegex() throws Exception{ + request.setTag("ms-1"); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + } + + @Test + void test_msTagSizeValidation() throws Exception { + request.setTag("core-name-should-not-exceed-fifty-chars-core-name-should-not-exceed-fifty-chars"); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + } + + @Test + void test_msServiceNameShouldFollowRegex() throws Exception{ + request.setServiceName("ms-1"); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + } + + @Test + void test_userShouldNotBeBlank(){ + request.setUser(" "); + Set<ConstraintViolation<MicroserviceCreateRequest>> violations = validator.validate(request); + Assertions.assertThat(violations.size()).isEqualTo(1); + } +} @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.web.controller.SpecificationController; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.web.servlet.MockMvc; + +import static org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother.asJsonString; +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.MS_INSTANCE_ID; +import static org.onap.dcaegen2.platform.mod.objectmothers.SpecificationObjectMother.getMockSpecification; +import static org.onap.dcaegen2.platform.mod.objectmothers.SpecificationObjectMother.getSpecificationRequest; +import static org.hamcrest.Matchers.notNullValue; +import static org.mockito.Mockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@ExtendWith(SpringExtension.class) +@WebMvcTest(SpecificationController.class) +public class SpecificationControllerTest { + + @Autowired + MockMvc mockMvc; + + @MockBean + private SpecificationService mockSpecificationService; + + @BeforeEach + void setup() { + } + + @Test + void test_addSpecification_returnsSpecification() throws Exception { + //arrange + SpecificationRequest specificationRequest = getSpecificationRequest(); + Specification specification = getMockSpecification(DeploymentType.DOCKER); + + when(mockSpecificationService.createSpecification(MS_INSTANCE_ID, specificationRequest)).thenReturn(specification); + + //act/assert + mockMvc.perform(post("/api/specification/" + MS_INSTANCE_ID) + .contentType(MediaType.APPLICATION_JSON) + .content(asJsonString(specificationRequest)).accept(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$.id", notNullValue())) + .andExpect(status().isCreated()); + verify(mockSpecificationService, times(1)).createSpecification(MS_INSTANCE_ID, specificationRequest); + } + +}
\ No newline at end of file @@ -0,0 +1,209 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.MsInstanceInfo; +import org.onap.dcaegen2.platform.mod.model.exceptions.msinstance.MsInstanceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.MsInstanceRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.MsService; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceGateway; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceServiceImpl; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceStatusChangeHandler; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class MsInstanceServiceImplTest { + + @Spy + private MsInstanceServiceImpl service = new MsInstanceServiceImpl(); + + @Mock + private MsInstanceGateway msInstanceRepository; + + @Mock + private MsService msService; + + @Mock + private SpecificationService specificationService; + + @Mock + private DeploymentArtifactService deploymentArtifactService; + + @Mock + private MsInstanceStatusChangeHandler msInstanceStatusChangeHandler; + + + @BeforeEach + void setUp() { + service.setMsService(msService); + service.setSpecificationService(specificationService); + service.setDeploymentArtifactService(deploymentArtifactService); + service.setMsInstanceRepository(msInstanceRepository); + service.setMsInstanceStatusChangeHandler(msInstanceStatusChangeHandler); + } + + @Test + void getAll() { + MsInstance instance_1 = MsInstance.builder().id("123").build(); + MsInstance instance_2 = MsInstance.builder().id("345").build(); + + when(msInstanceRepository.findAll()).thenReturn(Arrays.asList(instance_1, instance_2)); + + List<MsInstance> instances = service.getAll(); + + assertThat(instances.size()).isEqualTo(2); + verify(msInstanceRepository, times(1)).findAll(); + } + + @Test + void test_getMsInstanceById() throws Exception{ + MsInstance expected = MsInstanceObjectMother.createMsInstance(); + + when(msInstanceRepository.findById(MS_INSTANCE_ID)).thenReturn(Optional.of(expected)); + + MsInstance original = service.getMsInstanceById(MS_INSTANCE_ID); + + assertThat(original.getId()).isEqualTo(expected.getId()); + } + + @Test + void test_msIntanceNotFound_willRaiseException() throws Exception{ + when(msInstanceRepository.findById(MS_INSTANCE_ID)).thenReturn(Optional.empty()); + assertThatExceptionOfType(MsInstanceNotFoundException.class).isThrownBy( + () -> service.getMsInstanceById(MS_INSTANCE_ID)); + } + + //TODO require cleaning and more assertions + @Test + void createMicroserviceInstance() { + + BaseMicroservice microservice = BaseMsObjectMother.createMockMsObject(); + MsInstanceRequest request = getMsInstanceMockRequest(); + MsInstance msInstanceMockDao = createMsInstance(); + + when(msService.getMicroserviceByName(BaseMsObjectMother.BASE_MS_NAME)).thenReturn(microservice); + when(msInstanceRepository.findByNameAndRelease(request.getName(), request.getRelease())) + .thenReturn(Optional.empty()); + when(msInstanceRepository.save(any())).thenReturn(msInstanceMockDao); + + MsInstance msInstance = service.createMicroserviceInstance(BaseMsObjectMother.BASE_MS_NAME,request); + + assertThat(msInstance.getId()).isEqualTo(msInstance.getId()); + assertThat(msInstance.getName()).isEqualTo(msInstance.getName()); + assertThat(msInstance.getMsInfo().keySet()).isEqualTo(msInstanceMockDao.getMsInfo().keySet()); + + verify(msService, times(1)).getMicroserviceByName(BaseMsObjectMother.BASE_MS_NAME); + verify(msInstanceRepository, times(1)).save(any(MsInstance.class)); + verify(msService, times(1)). + saveMsInstanceReferenceToMs(microservice, msInstance); + + } + + @Test + void test_updateMsInstance() { + + } + + @Test + void updateStatusBasedOnDeploymentArtifactsStatuses() { + MsInstance msInstance = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + when(msInstanceRepository.findById(msInstance.getId())).thenReturn(Optional.of(msInstance)); + + service.updateStatusBasedOnDeploymentArtifactsStatuses(msInstance.getId()); + + verify(msInstanceStatusChangeHandler, times(1)).updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + verify(service, times(1)).updateMsInstance(msInstance); + + } + + @Test + void test_removeDeploymentArtifactFromMsInstance() { + MsInstance msInstance = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + DeploymentArtifact deploymentArtifact = createDeploymentArtifact(msInstance); + + when(msInstanceRepository.findById(msInstance.getId())).thenReturn(Optional.of(msInstance)); + //when(msInstanceStatusChangeHandler.updateStatusBasedOnDeploymentArtifactsStatuses(any())).thenReturn(msInstance); + + service.removeDeploymentArtifactFromMsInstance(deploymentArtifact); + + assertThat(msInstance.getDeploymentArtifactsInfo().getDeploymentArtifacts().contains(deploymentArtifact.getId())).isFalse(); + verify(msInstanceStatusChangeHandler, times(1)).updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + verify(service, times(1)).updateMsInstance(msInstance); + + } + + @Test + void updateMicroserviceReference() throws Exception{ + BaseMicroservice microservice = BaseMsObjectMother.createMockMsObject(); + MsInstance msInstance_1 = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + msInstance_1.setId("instance-1"); + msInstance_1.getMsInfo().put("name", "old-ms"); + MsInstance msInstance_2 = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + msInstance_2.setId("instance-2"); + msInstance_2.getMsInfo().put("name", "old-ms"); + + when(msInstanceRepository.findById("instance-1")).thenReturn(Optional.of(msInstance_1)); + when(msInstanceRepository.findById("instance-2")).thenReturn(Optional.of(msInstance_2)); + + service.updateMicroserviceReference(microservice); + + assertThat(msInstance_1.getName()).isEqualTo(microservice.getName()); + assertThat(msInstance_2.getName()).isEqualTo(microservice.getName()); + + assertThat(msInstance_1.getMsInfo().get("name")).isEqualTo(microservice.getName()); + assertThat(msInstance_2.getMsInfo().get("name")).isEqualTo(microservice.getName()); + + verify(service, times(2)).getMsInstanceById(anyString()); + verify(msInstanceRepository, times(2)).save(any(MsInstance.class)); + } + + private DeploymentArtifact createDeploymentArtifact(MsInstance msInstance) { + DeploymentArtifact deploymentArtifact = new DeploymentArtifact(); + deploymentArtifact.setId(msInstance.getDeploymentArtifactsInfo().getDeploymentArtifacts().get(0)); + + MsInstanceInfo msInstanceInfo = new MsInstanceInfo(); + msInstanceInfo.setId(msInstance.getId()); + deploymentArtifact.setMsInstanceInfo(msInstanceInfo); + return deploymentArtifact; + } +}
\ No newline at end of file @@ -0,0 +1,92 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service; + +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstanceStatus; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.deploymentartifact.DeploymentArtifactService; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceStatusChangeHandler; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class MsInstanceStatusChangeHandlerTest { + + MsInstanceStatusChangeHandler statusChangeHandler; + + @Mock + MsInstanceService msInstanceService; + + @Mock + DeploymentArtifactService deploymentArtifactService; + + @BeforeEach + void setup() throws Exception{ + statusChangeHandler = new MsInstanceStatusChangeHandler(); + statusChangeHandler.setMsInstanceService(msInstanceService); + statusChangeHandler.setDeploymentArtifactService(deploymentArtifactService); + } + + @Test + void handleStatusChangeFromDeploymentArtifactsWithDevComplete() { + //arrange + MsInstance msInstance = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + + when(deploymentArtifactService.findByMsInstanceId(msInstance.getId())).thenReturn( + DeploymentArtifactObjectMother.createMockDeploymentArtifactsWithDifferentStatuses(true) + ); + + //act + statusChangeHandler.updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + + //assert + assertThat(msInstance.getStatus()).isEqualTo(MsInstanceStatus.DEV_COMPLETE); + verify(deploymentArtifactService, times(1)).findByMsInstanceId(msInstance.getId()); + } + + @Test + void handleStatusChangeFromDeploymentArtifactsWithoutDevComplete() { + //arrange + MsInstance msInstance = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + + //when(msInstanceService.getMsInstanceById(msInstance.getId())).thenReturn(msInstance); + when(deploymentArtifactService.findByMsInstanceId(msInstance.getId())).thenReturn( + DeploymentArtifactObjectMother.createMockDeploymentArtifactsWithDifferentStatuses(false) + ); + + //act + statusChangeHandler.updateStatusBasedOnDeploymentArtifactsStatuses(msInstance); + + //assert + assertThat(msInstance.getStatus()).isEqualTo(MsInstanceStatus.IN_DEV); + verify(deploymentArtifactService, times(1)).findByMsInstanceId(msInstance.getId()); + } + +}
\ No newline at end of file @@ -0,0 +1,217 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service; + +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMicroservice; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsLocation; +import org.onap.dcaegen2.platform.mod.model.basemicroservice.BaseMsType; +import org.onap.dcaegen2.platform.mod.model.exceptions.ResourceConflictException; +import org.onap.dcaegen2.platform.mod.model.exceptions.basemicroservice.BaseMicroserviceNotFoundException; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceCreateRequest; +import org.onap.dcaegen2.platform.mod.model.restapi.MicroserviceUpdateRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.BaseMicroserviceGateway; +import org.onap.dcaegen2.platform.mod.web.service.basemicroservice.MsServiceImpl; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.*; + +import static org.onap.dcaegen2.platform.mod.model.exceptions.ErrorMessages.MICROSERVICE_NAME_CONFLICT_MESSAGE; +import static org.onap.dcaegen2.platform.mod.model.exceptions.ErrorMessages.MICROSERVICE_TAG_CONFLICT_MESSAGE; +import static org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother.createMockMsObject; +import static org.onap.dcaegen2.platform.mod.objectmothers.BaseMsObjectMother.createMockMsRequest; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class MsServiceImplTest { + + @Mock + private BaseMicroserviceGateway repository; + + @Mock + private MsInstanceService msInstanceService; + + @Spy + private MsServiceImpl baseMsService = new MsServiceImpl(); + + @BeforeEach + void setup() throws Exception{ + baseMsService.setRepository(repository); + baseMsService.setMsInstanceService(msInstanceService); + } + + /**GET MICROSERVICE TESTS*/ + @Test + void getAll() { + //arrange + BaseMicroservice ms1 = new BaseMicroservice(); + ms1.setName("HelloWorld1"); + BaseMicroservice ms2 = new BaseMicroservice(); + ms2.setName("HelloWorld2"); + + when(repository.findAll()).thenReturn(Arrays.asList(ms1, ms2)); + + //act + List<BaseMicroservice> microservices = baseMsService.getAllMicroservices(); + + //assert + assertThat(microservices).hasSizeGreaterThan(0); + } + + @Test + void test_getMicroserviceById() throws Exception{ + BaseMicroservice expectedMicroservice = BaseMsObjectMother.createMockMsObject(); + String baseMsId = BaseMsObjectMother.BASE_MS_ID; + + when(repository.findById(baseMsId)).thenReturn(Optional.of(expectedMicroservice)); + + BaseMicroservice resultMicroservice = baseMsService.getMicroserviceById(baseMsId); + + assertThat(resultMicroservice).isEqualTo(expectedMicroservice); + verify(repository, times(1)).findById(baseMsId); + } + + @Test + void test_ifMicroserviceNotFoundRaiseException() throws Exception{ + BaseMicroservice expectedMicroservice = BaseMsObjectMother.createMockMsObject(); + String baseMsId = BaseMsObjectMother.BASE_MS_ID; + + when(repository.findById(baseMsId)).thenReturn(Optional.empty()); + + assertThatExceptionOfType(BaseMicroserviceNotFoundException.class).isThrownBy( + () -> baseMsService.getMicroserviceById(baseMsId) + ); + } + + /**CREATE MICROSERVICE TESTS*/ + @Test + void createMicroservice() { + //arrange + MicroserviceCreateRequest microserviceRequest = createMockMsRequest(); + BaseMicroservice expected = createMockMsObject(); + + when(repository.save(any())).thenReturn(expected); + + //act + BaseMicroservice actual = baseMsService.createMicroservice(microserviceRequest); + + //assert + assertThat(actual.getMetadata().getCreatedBy()).isEqualTo(microserviceRequest.getUser()); + assertThat(actual.getMetadata().getUpdatedBy()).isEqualTo(microserviceRequest.getUser()); + } + + @Test + void AddingMsWithDuplicateName_shouldThrowException() throws Exception{ + //arrange + MicroserviceCreateRequest microserviceRequest = createMockMsRequest(); + BaseMicroservice existedMicroservice = createMockMsObject(); + + when(repository.findByName(any())).thenReturn(Optional.of(existedMicroservice)); + + //act/assert + assertThatThrownBy(() -> baseMsService.createMicroservice((microserviceRequest))) + .isInstanceOf(ResourceConflictException.class) + .hasMessage(MICROSERVICE_NAME_CONFLICT_MESSAGE); + } + @Test + void AddingMsWithDuplicateTag_shouldThrowException() throws Exception{ + //arrange + MicroserviceCreateRequest microserviceRequest = createMockMsRequest(); + BaseMicroservice existedMicroservice = createMockMsObject(); + + when(repository.findByTag(any())).thenReturn(Optional.of(existedMicroservice)); + + //act/assert + assertThatThrownBy(() -> baseMsService.createMicroservice((microserviceRequest))) + .isInstanceOf(ResourceConflictException.class) + .hasMessage(MICROSERVICE_TAG_CONFLICT_MESSAGE); + } + + /**UPDATE MICROSERVICE TESTS*/ + @Test + void test_updateMicroservice() throws Exception{ + MicroserviceUpdateRequest updateRequest = createUpdateMsRequest(); + + BaseMicroservice msToBeUpdated = BaseMsObjectMother.createMockMsObject(); + Date updateTimeBefore = new Date(msToBeUpdated.getMetadata().getUpdatedOn().getTime()); + + String baseMsId = BaseMsObjectMother.BASE_MS_ID; + + when(repository.findById(baseMsId)).thenReturn(Optional.of(msToBeUpdated)); + + baseMsService.updateMicroservice(baseMsId, updateRequest); + + //assert + assertUpdatedMsFileds(updateRequest, msToBeUpdated, updateTimeBefore); + verify(baseMsService, times(1)).getMicroserviceById(baseMsId); + verify(msInstanceService, times(1)).updateMicroserviceReference(msToBeUpdated); + verify(repository, times(1)).save(msToBeUpdated); + } + +/* @Test + void test_msTagChangeShouldNotBeAllowed() throws Exception{ + MicroserviceCreateRequest updateRequest = new MicroserviceCreateRequest(); + updateRequest.setTag("updateTag"); + String baseMsId = BaseMsObjectMother.BASE_MS_ID; + + assertThatExceptionOfType(OperationNotAllowedException.class).isThrownBy( + () -> baseMsService.updateMicroservice(baseMsId, updateRequest) + ); + }*/ + + private void assertUpdatedMsFileds(MicroserviceUpdateRequest updateRequest, BaseMicroservice msToBeUpdated, + Date updateTimeBefore) { + assertThat(msToBeUpdated.getName()).isEqualTo(updateRequest.getName()); + assertThat(msToBeUpdated.getLocation()).isEqualTo(updateRequest.getLocation()); + assertThat(msToBeUpdated.getServiceName()).isEqualTo(updateRequest.getServiceName()); + assertThat(msToBeUpdated.getNamespace()).isEqualTo(updateRequest.getNamespace()); + assertThat(msToBeUpdated.getType()).isEqualTo(updateRequest.getType()); + + assertThat(msToBeUpdated.getMetadata().getUpdatedBy()).isEqualTo(updateRequest.getUser()); + assertThat(msToBeUpdated.getMetadata().getUpdatedOn()).isNotEqualTo(updateTimeBefore); + + assertThat(msToBeUpdated.getMetadata().getNotes()).isEqualTo(updateRequest.getMetadata().get("notes")); + assertThat(msToBeUpdated.getMetadata().getLabels()).isEqualTo(updateRequest.getMetadata().get("labels")); + } + + private MicroserviceUpdateRequest createUpdateMsRequest() { + MicroserviceUpdateRequest updateRequest = new MicroserviceUpdateRequest(); + updateRequest.setName("updatedName"); + updateRequest.setLocation(BaseMsLocation.EDGE); + updateRequest.setServiceName("updatedServiceName"); + updateRequest.setNamespace("updatedNameSpace"); + updateRequest.setType(BaseMsType.ANALYTIC); + updateRequest.setUser("updater"); + + Map<String, Object> metadata = new HashMap(); + metadata.put("notes", "updatedNote"); + metadata.put("labels", Arrays.asList("updatedLabel1", "updatedLabel2")); + updateRequest.setMetadata(metadata); + return updateRequest; + } +}
\ No newline at end of file @@ -0,0 +1,103 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.SpecificationRequest; +import org.onap.dcaegen2.platform.mod.model.specification.Specification; +import org.onap.dcaegen2.platform.mod.model.specification.SpecificationStatus; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationGateway; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationServiceImpl; +import org.onap.dcaegen2.platform.mod.web.service.specification.SpecificationValidatorService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.MS_INSTANCE_ID; +import static org.onap.dcaegen2.platform.mod.objectmothers.SpecificationObjectMother.getMockSpecification; +import static org.onap.dcaegen2.platform.mod.objectmothers.SpecificationObjectMother.getSpecificationRequest; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith({MockitoExtension.class}) +public class SpecificationServiceTest { + + private SpecificationServiceImpl service; + + @Mock + private SpecificationGateway specRepo; + + @Mock + private MsInstanceService msInstanceService; + + @Mock + private SpecificationValidatorService validatorService; + + @BeforeEach + void setUp() { + service = new SpecificationServiceImpl(); + service.setMsInstanceService(msInstanceService); + service.setSpecificationValidatorService(validatorService); + service.setSpecificationGateway(specRepo); + } + + @Test + void createSpecificationTest() throws Exception { + //given + SpecificationRequest request = getSpecificationRequest(); + Specification specFromRepo = getMockSpecification(DeploymentType.K8S); + MsInstance msInstance = MsInstanceObjectMother.createMsInstance(); + + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + when(specRepo.save(any(Specification.class))).thenReturn(specFromRepo); + + //when + Specification spec = service.createSpecification(MS_INSTANCE_ID, request); + + //then + assertThatFieldsAreCorrect(request, spec); + verifyCalls(request, msInstance); + + } + + private void assertThatFieldsAreCorrect(SpecificationRequest request, Specification spec) { + assertThat(spec.getStatus()).isEqualTo(SpecificationStatus.ACTIVE); + assertThat(spec.getSpecContent()).isEqualTo(request.getSpecContent()); + assertThat(spec.getPolicyJson()).isEqualTo(request.getPolicyJson()); + assertThat(spec.getType()).isEqualTo(request.getType()); + assertThat(spec.getMetadata().get("createdBy")).isEqualTo(request.getUser()); + assertThat(spec.getMetadata().get("createdOn")).isNotNull(); + assertThat(spec.getMsInstanceInfo()).isNotNull(); + } + + private void verifyCalls(SpecificationRequest request, MsInstance msInstance) { + verify(msInstanceService, times(1)).getMsInstanceById(MS_INSTANCE_ID); + verify(validatorService, times(1)).validateSpecForRelease(request, msInstance.getRelease()); + verify(specRepo, times(2)).save(any(Specification.class)); + verify(msInstanceService, times(1)).updateMsInstance(msInstance); + } +} @@ -0,0 +1,89 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.specification.DeploymentType; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.BlueprintFileNameCreateException; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.HashMap; + +class ArtifactFileNameCreatorTest { + + private ArtifactFileNameCreator fileNameCreator; + + @BeforeEach + void setUp() { + fileNameCreator = new ArtifactFileNameCreator(); + } + + @Test + void test_createCorrectBlueprintFileName() throws Exception{ + //arrange + MsInstance msInstance = MsInstanceObjectMother.createMsInstance(); + String expectedName = createExpectedName(msInstance); + + //act + String fileName = fileNameCreator.createFileName(msInstance, 1); + + //assert + Assertions.assertThat(fileName).isEqualTo(expectedName); + } + + @Test + void test_missingTagForFileNameCreation_ShouldRaiseException() throws Exception{ + + //arrange + MsInstance msInstance = MsInstanceObjectMother.createMsInstance(); + msInstance.setMsInfo(new HashMap<>()); + + Assertions.assertThatExceptionOfType(BlueprintFileNameCreateException.class).isThrownBy( + () -> fileNameCreator.createFileName(msInstance, 1) + ); + } + + @Test + void test_missingSpecForFileNameCreation_ShouldRaiseException() throws Exception{ + + //arrange + MsInstance msInstance = MsInstanceObjectMother.createMsInstance(); + msInstance.setActiveSpec(null); + + Assertions.assertThatExceptionOfType(BlueprintFileNameCreateException.class).isThrownBy( + () -> fileNameCreator.createFileName(msInstance, 1) + ); + } + + + private String createExpectedName(MsInstance msInstance) { + String fileName = MsInstanceObjectMother.BASE_MS_TAG + "_" + + DeploymentType.DOCKER.toString().toLowerCase() + "_" + + msInstance.getRelease() + "_" + + "1" + + ".yaml"; + + return fileName; + } +}
\ No newline at end of file @@ -0,0 +1,250 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.DeploymentArtifactNotFound; +import org.onap.dcaegen2.platform.mod.model.microserviceinstance.MsInstance; +import org.onap.dcaegen2.platform.mod.model.restapi.DeploymentArtifactPatchRequest; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother; +import org.onap.dcaegen2.platform.mod.web.service.microserviceinstance.MsInstanceService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.onap.dcaegen2.platform.mod.objectmothers.MsInstanceObjectMother.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class DeploymentArtifactServiceImplTest { + + private DeploymentArtifactServiceImpl deploymentArtifactService; + + @Mock + private MsInstanceService msInstanceService; + + @Mock + private DeploymentArtifactGeneratorStrategy deploymentArtifactGeneratorStrategy; + + @Mock + private DeploymentArtifactGateway repository; + + @Mock + private ArtifactFileNameCreator fileNameCreator; + + @Mock + private DeploymentArtifactStatusChangeHandler deploymentArtifactStatusChangeHandler; + + private MsInstance msInstance; + + DeploymentArtifact deploymentArtifact; + + @BeforeEach + void setUp() { + //Initiated the deployment artifact core with mocks + deploymentArtifactService = new DeploymentArtifactServiceImpl(); + deploymentArtifactService.setDeploymentArtifactGeneratorStrategy(deploymentArtifactGeneratorStrategy); + deploymentArtifactService.setDeploymentArtifactGateway(repository); + deploymentArtifactService.setMsInstanceService(msInstanceService); + deploymentArtifactService.setFileNameCreator(fileNameCreator); + deploymentArtifactService.setStatusChangeHandler(deploymentArtifactStatusChangeHandler); + } + + private void setupMockBehaviours() { + //Mock methods + deploymentArtifact = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + msInstance = MsInstanceObjectMother.createMsInstance(); + + when(deploymentArtifactGeneratorStrategy.generateForRelease(msInstance.getActiveSpec(), msInstance.getRelease())) + .thenReturn(DeploymentArtifactObjectMother.createBlueprintResponse()); + when(repository.save(any())).thenReturn(deploymentArtifact); + when(fileNameCreator.createFileName(any(MsInstance.class), any(Integer.class))).thenReturn(BASE_MS_TAG + "_" + + msInstance.getActiveSpec().getType().toString().toLowerCase() + "_" + msInstance.getRelease() + "_1.yaml"); + } + + @Test + void test_getAllDeploymentArtifactInstance() throws Exception{ + when(repository.findAll()).thenReturn(Arrays.asList(deploymentArtifact)); + List<DeploymentArtifact> deployments = deploymentArtifactService.getAllDeploymentArtifacts(); + assertThat(deployments.size()).isEqualTo(1); + } + + @Test + void test_GenerateBlueprint_shouldReturnCorrectBlueprint() throws Exception{ + + setupMockBehaviours(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + + //act + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + + //assert + verify(msInstanceService, atLeastOnce()).getMsInstanceById(MS_INSTANCE_ID); + verify(repository, times(1)).save(any()); + assertThat(resultDAO.getContent()).contains("tosca_definitions_version"); + assertThat(resultDAO.getId()).isNotEmpty(); + assertThat(resultDAO.getVersion()).isEqualTo(1); + assertThat(resultDAO.getStatus()).isEqualTo(DeploymentArtifactStatus.IN_DEV); + assertThat(resultDAO.getMsInstanceInfo().getId()).isEqualTo(MS_INSTANCE_ID); + assertThat(resultDAO.getMsInstanceInfo().getName()).isEqualTo(msInstance.getName()); + assertThat(resultDAO.getMsInstanceInfo().getRelease()).isEqualTo(msInstance.getRelease()); + assertThat(resultDAO.getSpecificationInfo().get("id")).isNotNull(); + assertThat(resultDAO.getMetadata().get("createdBy")).isEqualTo(USER); + + } + + @Test + void test_deploymentVersionIsInitatedWith1() throws Exception{ + setupMockBehaviours(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + assertThat(resultDAO.getVersion()).isEqualTo(1); + } + + @Test + void test_deploymentVersionIncrementsForEachAddForAnInstance() throws Exception{ + setupMockBehaviours(); + MsInstance msInstanceWithRef = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstanceWithRef); + + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + + assertThat(resultDAO.getVersion()).isEqualTo(2); + } + + @Test + void test_deploymentArtifactRefAddedToMsInstanceForFirstTime() throws Exception{ + setupMockBehaviours(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + assertThat(msInstance.getDeploymentArtifactsInfo().getMostRecentVersion()).isEqualTo(1); + + List<String> deploymentArtifactList = msInstance.getDeploymentArtifactsInfo().getDeploymentArtifacts(); + assertThat(deploymentArtifactList.size()).isEqualTo(1); + assertThat(deploymentArtifactList.get(0)).isEqualTo(resultDAO.getId()); + } + + @Test + void test_deploymentArtifactRefAddedToMsInstanceForSecondTime() throws Exception{ + setupMockBehaviours(); + MsInstance msInstanceWithRef = MsInstanceObjectMother.getMsInstanceWithExistingDeploymentArtifactRef(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstanceWithRef); + + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + assertThat(msInstanceWithRef.getDeploymentArtifactsInfo().getMostRecentVersion()).isEqualTo(2); + + List<String> deploymentArtifactList = msInstanceWithRef.getDeploymentArtifactsInfo().getDeploymentArtifacts(); + assertThat(deploymentArtifactList.size()).isEqualTo(2); + assertThat(deploymentArtifactList.get(1)).isEqualTo(resultDAO.getId()); + } + + @Test + void test_ifMsInstanceIsPersistedAfterDeploymentArtifactCreation() throws Exception{ + setupMockBehaviours(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + verify(msInstanceService, times(1)).updateMsInstance(msInstance); + } + + @Test + void test_blueprintFileNameValidation() throws Exception{ + setupMockBehaviours(); + when(msInstanceService.getMsInstanceById(MS_INSTANCE_ID)).thenReturn(msInstance); + DeploymentArtifact resultDAO = deploymentArtifactService.generateDeploymentArtifact(MS_INSTANCE_ID, USER); + System.out.println(resultDAO.getFileName()); + assertThat(resultDAO.getFileName().contains(BASE_MS_TAG)).isTrue(); + } + + @Test + void test_updateStatusForDeploymentArtifact() throws Exception{ + //arrange + deploymentArtifact = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + + DeploymentArtifactPatchRequest dtoWithStatus = new DeploymentArtifactPatchRequest(); + dtoWithStatus.setStatus(DeploymentArtifactStatus.NOT_NEEDED); + + when(repository.findById("id-123")).thenReturn(Optional.of(deploymentArtifact)); + + //Mocking void method from DeploymentArtifactStatusChangeHandler + doAnswer(invocation -> { + deploymentArtifact.setStatus(DeploymentArtifactStatus.NOT_NEEDED); + return null; + }).when(deploymentArtifactStatusChangeHandler).handleStatusChange(dtoWithStatus.getStatus(), deploymentArtifact); + + //act + deploymentArtifactService.updateDeploymentArtifact("id-123", dtoWithStatus, "user1"); + + //assert + assertThat(deploymentArtifact.getStatus()).isEqualTo(DeploymentArtifactStatus.NOT_NEEDED); + assertThat(deploymentArtifact.getMetadata().get("updatedBy")).isEqualTo("user1"); + assertThat(deploymentArtifact.getMetadata().get("updatedOn")).isNotNull(); + + verify(deploymentArtifactStatusChangeHandler, times(1)).handleStatusChange(dtoWithStatus.getStatus(), + deploymentArtifact); + verify(msInstanceService, times(1)). + updateStatusBasedOnDeploymentArtifactsStatuses(deploymentArtifact.getMsInstanceInfo().getId()); + verify(repository, times(1)).save(deploymentArtifact); + } + + @Test + void test_findDeploymentArtifactById() throws Exception{ + //arrange + deploymentArtifact = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + when(repository.findById("id-123")).thenReturn(Optional.of(deploymentArtifact)); + + DeploymentArtifact result = deploymentArtifactService.findDeploymentArtifactById("id-123"); + + assertThat(result).isEqualTo(deploymentArtifact); + } + + @Test + void test_findByIdWithInvalidId() throws Exception{ + when(repository.findById("invalid-id")).thenReturn(Optional.empty()); + assertThatExceptionOfType(DeploymentArtifactNotFound.class).isThrownBy( + () -> deploymentArtifactService.findDeploymentArtifactById("invalid-id")); + } + + @Test + void test_deleteDeploymentArtifact() throws Exception{ + DeploymentArtifact deploymentArtifact = + DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + String id = deploymentArtifact.getId(); + + when(repository.findById(id)).thenReturn(Optional.of(deploymentArtifact)); + + deploymentArtifactService.deleteDeploymentArtifact(id); + verify(msInstanceService, times(1)) + .removeDeploymentArtifactFromMsInstance(deploymentArtifact); + verify(repository, times(1)).deleteById(id); + } +}
\ No newline at end of file @@ -0,0 +1,106 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.model.exceptions.deploymentartifact.StatusChangeNotValidException; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class DeploymentArtifactStatusChangeHandlerTest { + + DeploymentArtifactStatusChangeHandler artifactStatusChangeHandler; + + @Mock + DeploymentArtifactService deploymentArtifactService; + + @BeforeEach + void setUp() { + artifactStatusChangeHandler = new DeploymentArtifactStatusChangeHandler(); + artifactStatusChangeHandler.setDeploymentArtifactService(deploymentArtifactService); + } + + @Test + void test_DevCompleteToNotNeeded() throws Exception{ + //arrange + List<DeploymentArtifact> mockDeploymentArticats = DeploymentArtifactObjectMother.createMockDeploymentArtifactsWithDifferentStatuses(true); + DeploymentArtifact givenDAO = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.DEV_COMPLETE); + String msInstaneId = givenDAO.getMsInstanceInfo().getId(); + + when(deploymentArtifactService.findByMsInstanceId(msInstaneId)).thenReturn(mockDeploymentArticats); + + //act + artifactStatusChangeHandler.handleStatusChange(DeploymentArtifactStatus.NOT_NEEDED, givenDAO); + + assertThat(givenDAO.getStatus()).isEqualTo(DeploymentArtifactStatus.NOT_NEEDED); +// verify(msInstanceStatusChangeHandler, times(1)) +// .updateStatusBasedOnDeploymentArtifactsStatuses(msInstaneId); + + } + + @Test + void test_ValidateIfArtifactWithDevCompleteStatusNotFoundForTheSameInstance() throws Exception{ + //arrange + DeploymentArtifact givenDAO = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + String msInstaneId = givenDAO.getMsInstanceInfo().getId(); + + List<DeploymentArtifact> mockDeploymentArticats = DeploymentArtifactObjectMother.createMockDeploymentArtifactsWithDifferentStatuses(false); + when(deploymentArtifactService.findByMsInstanceId(msInstaneId)).thenReturn(mockDeploymentArticats); + + //act + artifactStatusChangeHandler.handleStatusChange(DeploymentArtifactStatus.DEV_COMPLETE, givenDAO); + + //assert + assertThat(givenDAO.getStatus()).isEqualTo(DeploymentArtifactStatus.DEV_COMPLETE); + verify(deploymentArtifactService, times(1)). + findByMsInstanceId(givenDAO.getMsInstanceInfo().getId()); +// verify(msInstanceStatusChangeHandler, times(1)) +// .updateStatusBasedOnDeploymentArtifactsStatuses(msInstaneId); + + } + + @Test + void DoesntValidateIfArtifactWithDevCompleteStatusAlreadyExistsForTheSameInstance() throws Exception{ + //arrange + DeploymentArtifact givenDAO = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + List<DeploymentArtifact> mockDeploymentArticats = DeploymentArtifactObjectMother.createMockDeploymentArtifactsWithDifferentStatuses(true); + when(deploymentArtifactService.findByMsInstanceId("id-123")).thenReturn(mockDeploymentArticats); + + //act/assert + assertThatExceptionOfType(StatusChangeNotValidException.class).isThrownBy( + () -> artifactStatusChangeHandler.handleStatusChange(DeploymentArtifactStatus.DEV_COMPLETE, givenDAO) + ); + + } + +}
\ No newline at end of file @@ -0,0 +1,90 @@ +/* + * ============LICENSE_START======================================================= + * org.onap.dcae + * ================================================================================ + * Copyright (c) 2020 AT&T Intellectual Property. 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.dcaegen2.platform.mod.web.service.deploymentartifact; + +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifact; +import org.onap.dcaegen2.platform.mod.model.deploymentartifact.DeploymentArtifactStatus; +import org.onap.dcaegen2.platform.mod.objectmothers.DeploymentArtifactObjectMother; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class SearchDeploymentArtifactsTest { + + private DeploymentArtifactServiceImpl service; + + @Mock + private DeploymentArtifactGateway repository; + + private DeploymentArtifact artifact_1; + private DeploymentArtifact artifact_2; + private DeploymentArtifact artifact_3; + + @BeforeEach + void setUp() { + service = new DeploymentArtifactServiceImpl(); + service.setDeploymentArtifactGateway(repository); + + //given + artifact_1 = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.IN_DEV); + artifact_1.getMsInstanceInfo().setRelease("2008"); + artifact_2 = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.DEV_COMPLETE); + artifact_2.getMsInstanceInfo().setRelease("2010"); + artifact_3 = DeploymentArtifactObjectMother.createDeploymentArtifactDAO(DeploymentArtifactStatus.DEV_COMPLETE); + artifact_3.getMsInstanceInfo().setRelease("2008"); + + } + +// @Test +// void findArtifacts_filteredWithRelease() throws Exception { +// List<DeploymentArtifact> artifacts = Arrays.asList(artifact_1, artifact_3); +// when(repository.findByReleaseOrStatusOfMsInstance("2008", null)).thenReturn(artifacts); +// +// //when +// DeploymentArtifactSearch search = new DeploymentArtifactSearch(); +// DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); +// filter.setRelease("2008"); +// search.setFilter(filter); +// +// List<DeploymentArtifact> result = core.searchDeploymentArtifacts(search); +// +// //assert +// assertThat(result.size()).isEqualTo(2); +// } +// +// @Test +// void findArtifacts_filteredWithStatus() throws Exception{ +// List<DeploymentArtifact> artifacts = Arrays.asList(artifact_2, artifact_3); +// when(repository.findByReleaseOrStatusOfMsInstance(null, DeploymentArtifactStatus.DEV_COMPLETE)) +// .thenReturn(artifacts); +// +// DeploymentArtifactSearch search = new DeploymentArtifactSearch(); +// DeploymentArtifactFilter filter = new DeploymentArtifactFilter(); +// filter.setStatus(DeploymentArtifactStatus.DEV_COMPLETE); +// search.setFilter(filter); +// +// List<DeploymentArtifact> result = core.searchDeploymentArtifacts(search); +// assertThat(result.size()).isEqualTo(2); +// +// } +} @@ -0,0 +1 @@ +#spring.data.mongodb.port=0
\ No newline at end of file @@ -0,0 +1,180 @@ +{ + "specContent": { + "self": { + "component_type": "docker", + "description": "Hello World mS for subscribing the data from local DMaaP, DR or MR, processing them and publishing them as PM files to local DMaaP DR", + "name": "dcae-collectors-vcc-helloworld-pm", + "version": "1.0.1" + }, + "services": { + "calls": [], + "provides": [] + }, + "streams": { + "publishes": [ + { + "config_key": "DCAE-HELLO-WORLD-PUB-DR", + "format": "dataformat_Hello_World_PM", + "type": "data_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-PUB-MR", + "format": "dataformat_Hello_World_PM", + "type": "message_router", + "version": "1.0.0" + } + ], + "subscribes": [ + { + "config_key": "DCAE-HELLO-WORLD-SUB-MR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE_HELLO_WORLD_SUB_MR", + "type": "message_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-SUB-DR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE-HELLO-WORLD-SUB-DR", + "type": "data_router", + "version": "1.0.0" + } + ] + }, + "parameters": [ + { + "name": "vcc_hello_name", + "value": "120", + "type": "integer", + "description": "the name entered for specific person", + "sourced_at_deployment": false, + "designer_editable": false, + "policy_editable": false + }, + { + "name": "useDtiConfig", + "value": false, + "type": "boolean", + "description": "component depends on configuration from dti.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required": true + }, + { + "name": "isSelfServeComponent", + "value": false, + "type": "boolean", + "description": "Is this used as self serve component.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required": true + } + ], + "auxilary": { + "healthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "livehealthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "reconfigs": { + "app_reconfig": "abc" + }, + "volumes": [ + { + "container": { + "bind": "/opt/app/dcae-certificate" + }, + "host": { + "path": "/opt/app/dcae-certificate" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/AGENT" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/AGENT" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/WATCHER" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/WATCHER" + } + }, + { + "container": { + "bind": "/opt/app/vcc/logs/DCAE" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/vcc-logs" + } + }, + { + "container": { + "bind": "/opt/app/vcc/archive/data" + }, + "host": { + "path": "/opt/data/DCAE/helloworldpm/vcc-archive" + } + } + ] + }, + "artifacts": [ + { + "type": "docker image", + "uri": "dockercentral.it.att.com:5100/com.att.sample/dcae-controller-vcc-helloworld-pm:18.02-001" + } + ] + }, + "policyJson": { + "policies": [ + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": false + }, + { + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": true + }, + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_*", + "unique": false + } + ], + "policy": [ + { + "policy_id": "id_0" + } + ] + }, + "type": "K8S", + "user": "abc123", + "metadata": { + "notes": "Sample 812-1", + "labels": [ + "LATEST" + ] + } +}
\ No newline at end of file @@ -0,0 +1,188 @@ +{ + "id": "5f3417a26aef7f07bc91350a", + "status": "ACTIVE", + "specContent": { + "self": { + "component_type": "docker", + "description": "Hello World mS for subscribing the data from local DMaaP, DR or MR, processing them and publishing them as PM files to local DMaaP DR", + "name": "dcae-collectors-vcc-helloworld-pm", + "version": "1.0.1" + }, + "services": { + "calls": [], + "provides": [] + }, + "streams": { + "publishes": [ + { + "config_key": "DCAE-HELLO-WORLD-PUB-DR", + "format": "dataformat_Hello_World_PM", + "type": "data_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-PUB-MR", + "format": "dataformat_Hello_World_PM", + "type": "message_router", + "version": "1.0.0" + } + ], + "subscribes": [ + { + "config_key": "DCAE-HELLO-WORLD-SUB-MR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE_HELLO_WORLD_SUB_MR", + "type": "message_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-SUB-DR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE-HELLO-WORLD-SUB-DR", + "type": "data_router", + "version": "1.0.0" + } + ] + }, + "parameters": [ + { + "name": "vcc_hello_name", + "value": "120", + "type": "integer", + "description": "the name entered for specific person", + "sourced_at_deployment": false, + "designer_editable": false, + "policy_editable": false + }, + { + "name": "useDtiConfig", + "value": false, + "type": "boolean", + "description": "component depends on configuration from dti.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required": true + }, + { + "name": "isSelfServeComponent", + "value": false, + "type": "boolean", + "description": "Is this used as self serve component.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required": true + } + ], + "auxilary": { + "healthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "livehealthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "reconfigs": { + "app_reconfig": "abc" + }, + "volumes": [ + { + "container": { + "bind": "/opt/app/dcae-certificate" + }, + "host": { + "path": "/opt/app/dcae-certificate" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/AGENT" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/AGENT" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/WATCHER" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/WATCHER" + } + }, + { + "container": { + "bind": "/opt/app/vcc/logs/DCAE" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/vcc-logs" + } + }, + { + "container": { + "bind": "/opt/app/vcc/archive/data" + }, + "host": { + "path": "/opt/data/DCAE/helloworldpm/vcc-archive" + } + } + ] + }, + "artifacts": [ + { + "type": "docker image", + "uri": "dockercentral.it.att.com:5100/com.att.sample/dcae-controller-vcc-helloworld-pm:18.02-001" + } + ] + }, + "policyJson": { + "policies": [ + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": false + }, + { + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": true + }, + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_*", + "unique": false + } + ], + "policy": [ + { + "policy_id": "id_0" + } + ] + }, + "type": "K8S", + "metadata": { + "notes": "Sample 812-1", + "labels": [ + "LATEST" + ], + "createdBy": "abc123", + "createdOn": "2020-08-12T16:24:02.621+0000" + }, + "msInstanceInfo": { + "release": "2006", + "name": "hello-804", + "id": "5f1592ffb551b604628316b0" + } +}
\ No newline at end of file @@ -0,0 +1,149 @@ +{ + "self": { + "component_type": "docker", + "description": "Hello World mS for subscribing the data from local DMaaP, DR or MR, processing them and publishing them as PM files to local DMaaP DR", + "name": "dcae-collectors-vcc-helloworld-pm", + "version": "1.0.1" + }, + + "services": { + "calls": [], + "provides": [] + }, + + "streams": { + "publishes": [{ + "config_key": "DCAE-HELLO-WORLD-PUB-DR", + "format": "dataformat_Hello_World_PM", + "type": "data_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-PUB-MR", + "format": "dataformat_Hello_World_PM", + "type": "message_router", + "version": "1.0.0" + } + ], + + "subscribes": [{ + "config_key": "DCAE-HELLO-WORLD-SUB-MR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE_HELLO_WORLD_SUB_MR", + "type": "message_router", + "version": "1.0.0" + }, + { + "config_key": "DCAE-HELLO-WORLD-SUB-DR", + "format": "dataformat_Hello_World_PM", + "route": "/DCAE-HELLO-WORLD-SUB-DR", + "type": "data_router", + "version": "1.0.0" + } + ] + }, + + "parameters": + [ + { + "name": "vcc_hello_name", + "value": "120", + "type": "integer", + "description": "the name entered for specific person", + "sourced_at_deployment": false, + "designer_editable": false, + "policy_editable": false + }, + + { + "name": "useDtiConfig", + "value": false, + "type" : "boolean", + "description": "component depends on configuration from dti.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required" : true + }, + + { + "name": "isSelfServeComponent", + "value": false, + "type": "boolean", + "description": "Is this used as self serve component.", + "sourced_at_deployment": false, + "designer_editable": true, + "policy_editable": false, + "required" : true + } + ], + + "auxilary": { + "healthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "livehealthcheck": { + "interval": "60s", + "initialDelaySeconds": "120s", + "timeout": "20s", + "script": "/opt/app/vcc/bin/common/HealthCheck_HelloWorld.sh", + "type": "docker" + }, + "reconfigs":{ + "app_reconfig" : "abc" + }, + + "volumes": [ + { + "container": { + "bind": "/opt/app/dcae-certificate" + }, + "host": { + "path": "/opt/app/dcae-certificate" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/AGENT" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/AGENT" + } + }, + { + "container": { + "bind": "/opt/logs/DCAE/dmd/WATCHER" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/dmd/WATCHER" + } + }, + { + "container": { + "bind": "/opt/app/vcc/logs/DCAE" + }, + "host": { + "path": "/opt/logs/DCAE/helloworldpm/vcc-logs" + } + }, + { + "container": { + "bind": "/opt/app/vcc/archive/data" + }, + "host": { + "path": "/opt/data/DCAE/helloworldpm/vcc-archive" + } + } + + ] + + }, + "artifacts": [{ + "type": "docker image", + "uri": "dockercentral.it.att.com:5100/com.att.sample/dcae-controller-vcc-helloworld-pm:18.02-001" + }] +}
\ No newline at end of file @@ -0,0 +1,28 @@ +{ + "policies": [ + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": false + }, + { + "onapName": "DCAE", + "policyName": "DCAE.Config_", + "unique": true + }, + { + "configAttributes": "", + "configName": "", + "onapName": "DCAE", + "policyName": "DCAE.Config_*", + "unique": false + } + ], + "policy": [ + { + "policy_id" : "id_0" + } + ] +}
\ No newline at end of file |