summaryrefslogtreecommitdiffstats
path: root/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web
diff options
context:
space:
mode:
Diffstat (limited to 'mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web')
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/AppExceptionHandler.java149
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/BaseMicroserviceController.java70
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/DeploymentArtifactController.java115
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/MicroserviceInstanceController.java75
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/SpecificationController.java62
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/BaseMicroserviceGateway.java45
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsService.java47
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsServiceImpl.java257
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/ArtifactFileNameCreator.java59
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGateway.java45
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGeneratorStrategy.java32
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactService.java51
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactServiceImpl.java205
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactStatusChangeHandler.java77
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceGateway.java40
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceService.java51
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceServiceImpl.java213
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceStatusChangeHandler.java75
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationGateway.java37
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationService.java40
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationServiceImpl.java138
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidationStratergy.java30
-rw-r--r--mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidatorService.java61
23 files changed, 1974 insertions, 0 deletions
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/AppExceptionHandler.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/AppExceptionHandler.java
new file mode 100644
index 0000000..1a2f5f9
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/AppExceptionHandler.java
@@ -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;
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/BaseMicroserviceController.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/BaseMicroserviceController.java
new file mode 100644
index 0000000..073b93a
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/BaseMicroserviceController.java
@@ -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);
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/DeploymentArtifactController.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/DeploymentArtifactController.java
new file mode 100644
index 0000000..e1cd512
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/DeploymentArtifactController.java
@@ -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);
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/MicroserviceInstanceController.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/MicroserviceInstanceController.java
new file mode 100644
index 0000000..14eb154
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/MicroserviceInstanceController.java
@@ -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);
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/SpecificationController.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/SpecificationController.java
new file mode 100644
index 0000000..854e7e6
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/controller/SpecificationController.java
@@ -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);
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/BaseMicroserviceGateway.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/BaseMicroserviceGateway.java
new file mode 100644
index 0000000..a516d90
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/BaseMicroserviceGateway.java
@@ -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
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsService.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsService.java
new file mode 100644
index 0000000..cdc1921
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsService.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsServiceImpl.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsServiceImpl.java
new file mode 100644
index 0000000..9cf46e6
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/basemicroservice/MsServiceImpl.java
@@ -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;
+
+ }
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/ArtifactFileNameCreator.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/ArtifactFileNameCreator.java
new file mode 100644
index 0000000..7713020
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/ArtifactFileNameCreator.java
@@ -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");
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGateway.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGateway.java
new file mode 100644
index 0000000..6bf2c2a
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGateway.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGeneratorStrategy.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGeneratorStrategy.java
new file mode 100644
index 0000000..9bb0870
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactGeneratorStrategy.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactService.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactService.java
new file mode 100644
index 0000000..3e7f899
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactService.java
@@ -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);
+}
+
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactServiceImpl.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactServiceImpl.java
new file mode 100644
index 0000000..8b97bba
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactServiceImpl.java
@@ -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;
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactStatusChangeHandler.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactStatusChangeHandler.java
new file mode 100644
index 0000000..48b18bf
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/deploymentartifact/DeploymentArtifactStatusChangeHandler.java
@@ -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());
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceGateway.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceGateway.java
new file mode 100644
index 0000000..12a510a
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceGateway.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceService.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceService.java
new file mode 100644
index 0000000..3c28f4d
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceService.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceServiceImpl.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceServiceImpl.java
new file mode 100644
index 0000000..e4d5694
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceServiceImpl.java
@@ -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;
+ }
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceStatusChangeHandler.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceStatusChangeHandler.java
new file mode 100644
index 0000000..bc26fab
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/microserviceinstance/MsInstanceStatusChangeHandler.java
@@ -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);
+ }
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationGateway.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationGateway.java
new file mode 100644
index 0000000..5fcfbb1
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationGateway.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationService.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationService.java
new file mode 100644
index 0000000..33724ac
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationService.java
@@ -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);
+}
+
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationServiceImpl.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationServiceImpl.java
new file mode 100644
index 0000000..7869801
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationServiceImpl.java
@@ -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);
+ });
+ }
+
+
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidationStratergy.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidationStratergy.java
new file mode 100644
index 0000000..58eff19
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidationStratergy.java
@@ -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);
+}
diff --git a/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidatorService.java b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidatorService.java
new file mode 100644
index 0000000..6d10aee
--- /dev/null
+++ b/mod2/catalog-service/src/main/java/org/onap/dcaegen2/platform/mod/web/service/specification/SpecificationValidatorService.java
@@ -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);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+