summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDivyang Patel <divyang.patel@team.telstra.com>2019-10-08 15:19:53 +1100
committerOfir Sonsino <ofir.sonsino@intl.att.com>2019-12-11 12:10:32 +0000
commitc2a53cb447789e15e85663ae253ab2d90b972934 (patch)
treeb2893949579a499e860d76844cf8a1a5471c4fa7
parentbbe2a934c76de7c0153854981de9a76258ca5564 (diff)
Add service creation API as an External API
Issue-ID: SDC-2383 Change-Id: I8490163310e892a7ebb6d7e7275edfdeba24045e Signed-off-by: Atif Husain <atif.husain@team.telstra.com>
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactory.java56
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java1239
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java28
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/AuditTestUtils.java7
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactoryTest.java131
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentsUtilsTest.java79
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServletTest.java42
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/impl/ComponentsUtilsTest.java12
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java1
-rw-r--r--common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnum.java110
-rw-r--r--common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnumTest.java129
-rw-r--r--docs/swagger/swagger.html4
-rw-r--r--docs/swagger/swagger.json6
13 files changed, 1221 insertions, 623 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactory.java b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactory.java
new file mode 100644
index 0000000000..640b537f60
--- /dev/null
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactory.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Telstra 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.openecomp.sdc.be.auditing.impl.externalapi;
+
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.resources.data.auditing.model.CommonAuditData;
+import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
+import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
+import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo;
+
+public class AuditCreateServiceExternalApiEventFactory extends AuditExternalApiEventFactory {
+
+ private static final String LOG_STR = "ACTION = \"%s\" RESOURCE_TYPE = \"%s\" CONSUMER_ID = \"%s\"" +
+ " RESOURCE_URL = \"%s\" MODIFIER = \"%s\" STATUS = \"%s\" SERVICE_INSTANCE_ID = \"%s\" INVARIANT_UUID = \"%s\" DESC = \"%s\"";
+
+ public AuditCreateServiceExternalApiEventFactory(CommonAuditData commonFields, ResourceCommonInfo resourceCommonInfo,
+ DistributionData distributionData, String invariantUuid, User modifier) {
+ super(AuditingActionEnum.CREATE_SERVICE_BY_API, commonFields, resourceCommonInfo, distributionData,
+ ResourceVersionInfo.newBuilder()
+ .build(),
+ ResourceVersionInfo.newBuilder()
+ .build(),
+ invariantUuid, modifier, null);
+ }
+
+ @Override
+ public String getLogPattern() {
+ return LOG_STR;
+ }
+
+ @Override
+ public String[] getLogMessageParams() {
+ return new String[] {event.getAction(), event.getResourceType(), event.getConsumerId(),
+ event.getResourceURL(), event.getModifier(), event.getStatus(),
+ event.getServiceInstanceId(), event.getInvariantUuid(), event.getDesc()};
+ }
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java
index b4c9c42867..bca588ad14 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/CrudExternalServlet.java
@@ -1,585 +1,654 @@
-/*-
- * ============LICENSE_START=======================================================
- * SDC
- * ================================================================================
- * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-import javax.inject.Inject;
-import javax.inject.Singleton;
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import org.apache.commons.lang3.StringUtils;
-import org.elasticsearch.common.Strings;
-import org.json.simple.JSONObject;
-import org.json.simple.parser.JSONParser;
-import org.json.simple.parser.ParseException;
-import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
-import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
-import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
-import org.openecomp.sdc.be.components.impl.ResourceImportManager;
-import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
-import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
-import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase;
-import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
-import org.openecomp.sdc.be.config.BeEcompErrorManager;
-import org.openecomp.sdc.be.dao.api.ActionStatus;
-import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
-import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
-import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
-import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter;
-import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata;
-import org.openecomp.sdc.be.impl.ComponentsUtils;
-import org.openecomp.sdc.be.impl.ServletUtils;
-import org.openecomp.sdc.be.model.Component;
-import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
-import org.openecomp.sdc.be.model.Resource;
-import org.openecomp.sdc.be.model.User;
-import org.openecomp.sdc.be.model.category.CategoryDefinition;
-import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
-import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
-import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
-import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
-import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
-import org.openecomp.sdc.be.servlets.RepresentationUtils;
-import org.openecomp.sdc.be.user.UserBusinessLogic;
-import org.openecomp.sdc.be.utils.CommonBeUtils;
-import org.openecomp.sdc.common.api.Constants;
-import org.openecomp.sdc.common.datastructure.Wrapper;
-import org.openecomp.sdc.common.log.wrappers.Logger;
-import org.openecomp.sdc.common.util.ValidationUtils;
-import org.openecomp.sdc.exception.ResponseFormat;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.jcabi.aspects.Loggable;
-import fj.data.Either;
-import io.swagger.v3.oas.annotations.OpenAPIDefinition;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.info.Info;
-import io.swagger.v3.oas.annotations.media.ArraySchema;
-import io.swagger.v3.oas.annotations.media.Content;
-import io.swagger.v3.oas.annotations.media.Schema;
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-
-@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
-@Path("/v1/catalog")
-@OpenAPIDefinition(info = @Info(title = "CRUD External Servlet",
- description = "This Servlet serves external users for creating assets and changing their lifecycle state"))
-
-@Singleton
-public class CrudExternalServlet extends AbstractValidationsServlet {
-
- @Context
- private HttpServletRequest request;
-
- private static final Logger log = Logger.getLogger(CrudExternalServlet.class);
- private final ElementBusinessLogic elementBusinessLogic;
- private final AssetMetadataConverter assetMetadataUtils;
- private final LifecycleBusinessLogic lifecycleBusinessLogic;
- private final ResourceBusinessLogic resourceBusinessLogic;
-
- @Inject
- public CrudExternalServlet(UserBusinessLogic userBusinessLogic,
- ComponentInstanceBusinessLogic componentInstanceBL,
- ComponentsUtils componentsUtils, ServletUtils servletUtils,
- ResourceImportManager resourceImportManager,
- ElementBusinessLogic elementBusinessLogic,
- AssetMetadataConverter assetMetadataUtils,
- LifecycleBusinessLogic lifecycleBusinessLogic,
- ResourceBusinessLogic resourceBusinessLogic) {
- super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
- this.elementBusinessLogic = elementBusinessLogic;
- this.assetMetadataUtils = assetMetadataUtils;
- this.lifecycleBusinessLogic = lifecycleBusinessLogic;
- this.resourceBusinessLogic = resourceBusinessLogic;
- }
-
- /**
- * Creates a new Resource
- *
- * @param assetType
- * @param data
- * @param userId
- * @param instanceIdHeader
- * @return
- */
- @POST
- @Path("/{assetType}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @Operation(description = "creates a resource", method = "POST", summary = "Creates a resource")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "ECOMP component is authenticated and Asset created",
- content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
- @ApiResponse(responseCode = "400", description = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
- @ApiResponse(responseCode = "401",
- description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
- @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
- @ApiResponse(responseCode = "404",
- description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
- @ApiResponse(responseCode = "405",
- description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
- @ApiResponse(responseCode = "500",
- description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
- @ApiResponse(responseCode = "400",
- description = "The name provided for the newly created resource is already in use for another resource in SDC - SVC4050"),
- @ApiResponse(responseCode = "400",
- description = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"),
- @ApiResponse(responseCode = "400",
- description = "Missing request body. The post request did not contain the expected body - SVC4500"),
- @ApiResponse(responseCode = "400",
- description = "The resource name is missing in the request body - SVC4062"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT description has wrong format - SVC4064"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT description has wrong format (exceeds limit) - SVC4065"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT tags exceeds character limit - SVC4066"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT vendor name exceeds character limit - SVC4067"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT vendor release exceeds character limit - SVC4068"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT ATT Contact has wrong format - SVC4069"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT name has wrong format - SVC4070"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT vendor name has wrong format - SVC4071"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT vendor release has wrong format - SVC4072"),
- @ApiResponse(responseCode = "400",
- description = "Create VFCMT request: VFCMT name exceeds character limit - SVC4073")})
- // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType =
- // "org.openecomp.sdc.be.model.Resource", paramType = "body", value = "json describe the created
- // resource")})
- public Response createResourceExternal(
- @Parameter(description = "Determines the format of the body of the request",
- required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
- @Parameter(description = "The user id",
- required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
- @Parameter(description = "X-ECOMP-RequestID header",
- required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
- @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
- value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
- @Parameter(description = "Determines the format of the body of the response",
- required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
- @Parameter(description = "The username and password",
- required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
- @Parameter(description = "The requested asset type", required = true,
- schema = @Schema(
- allowableValues = {"resources, services"})) @PathParam("assetType") final String assetType,
- @Parameter(hidden = true) String data) {
-
- init();
-
- Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
- String requestURI = request.getRequestURI();
- String url = request.getMethod() + " " + requestURI;
- log.debug("Start handle request of {}", url);
- Resource resource = null;
- User modifier = null;
- ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(ComponentTypeEnum.RESOURCE.getValue());
-
- ServletContext context = request.getSession().getServletContext();
- try {
- // Validate X-ECOMP-InstanceID Header
- if (responseWrapper.isEmpty()) {
- validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
- }
- // Validate USER_ID Header
- if (responseWrapper.isEmpty()) {
- validateHttpCspUserIdHeader(userId, responseWrapper);
- }
- // Validate assetType
- if (responseWrapper.isEmpty()) {
- if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) ){
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
- }
- }
- //Validate resource type
- if(responseWrapper.isEmpty()){
- JSONParser parser = new JSONParser();
- JSONObject jsonObj = (JSONObject) parser.parse(data);
- String resourceType = (String) jsonObj.get(FilterKeyEnum.RESOURCE_TYPE.getName());
- if( StringUtils.isEmpty(resourceType) || !ResourceTypeEnum.containsName(resourceType) ){
- resourceCommonInfo.setResourceName((String) jsonObj.get("name"));
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
- }
- }
- // Convert the user json to a resource
- if (responseWrapper.isEmpty()) {
- modifier = new User();
- modifier.setUserId(userId);
- Either<Resource, ResponseFormat> eitherResource = getComponentsUtils()
- .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class,
- null, ComponentTypeEnum.RESOURCE);
- if( eitherResource.isRight() ){
- responseWrapper.setInnerElement(eitherResource.right().value());
- }
- else{
- resource = eitherResource.left().value();
- }
-
- }
- //validate name exist
- if(responseWrapper.isEmpty()){
- if( Strings.isEmpty(resource.getName())){
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
- ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue()));
-
- }
- }
-
- if(responseWrapper.isEmpty()){
- resource.setDerivedFrom(Arrays.asList("tosca.nodes.Root"));
- resource.setSystemName(ValidationUtils.convertToSystemName(resource.getName()));
- resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VFCMT.name(),
- resource.getSystemName()));
- handleCategories(context, data, resource, responseWrapper);
- }
- // Create the resource in the dataModel
- if (responseWrapper.isEmpty()) {
- resource = resourceBusinessLogic.createResource(resource, null,
- modifier, null, null);
- return buildCreatedResourceResponse(resource, context, responseWrapper);
- } else {
- return buildErrorResponse(responseWrapper.getInnerElement());
- }
- } catch (IOException|ParseException e) {
- final String message = "failed to create vfc monitoring template resource";
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
- log.debug(message, e);
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
- return buildErrorResponse(responseWrapper.getInnerElement());
- } catch (ComponentException e){
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
- finally{
- getComponentsUtils().auditCreateResourceExternalApi(responseWrapper.getInnerElement(), resourceCommonInfo, request, resource);
- }
- }
-
- /**
- * Changing the lifecycle of an asset
- * @param jsonChangeInfo The description - request body
- * @param assetType The requested asset type.Valid values are: resources / services (for VFCMT – use "resources")
- * @param uuid The uuid of the desired resource to be changed
- * @param lifecycleTransition The lifecycle operation to be performed on the asset.Valid values are:Checkin / Checkout / CERTIFICATION_REQUEST
- * @param userId
- * @return
- */
- @POST
- @Path("/{assetType}/{uuid}/lifecycleState/{lifecycleOperation}")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- @Operation(description = "Change Resource lifecycle State", method = "POST")
- @ApiResponses(value = {
- @ApiResponse(responseCode = "200", description = "Resource state changed",
- content = @Content(array = @ArraySchema(schema = @Schema(implementation = AssetMetadata.class)))),
- @ApiResponse(responseCode = "400", description = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
- @ApiResponse(responseCode = "401",
- description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
- @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
- @ApiResponse(responseCode = "404",
- description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
- @ApiResponse(responseCode = "405",
- description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
- @ApiResponse(responseCode = "500",
- description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
- @ApiResponse(responseCode = "403", description = "Asset is already checked-out by another user - SVC4085"),
- @ApiResponse(responseCode = "403",
- description = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4080")})
- // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction", paramType = "body", value = "userRemarks - Short description (free text) about the asset version being changed")})
- public Response changeResourceStateExternal(
- @Parameter(description = "Determines the format of the body of the request",
- required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
- @Parameter(description = "The user id",
- required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
- @Parameter(description = "X-ECOMP-RequestID header",
- required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
- @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
- value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
- @Parameter(description = "Determines the format of the body of the response",
- required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
- @Parameter(description = "The username and password",
- required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
- @Parameter(schema = @Schema(allowableValues = {"checkout, checkin"}),
- required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition,
- @Parameter(description = "id of component to be changed") @PathParam(value = "uuid") final String uuid,
- @Parameter(description = "validValues: resources / services ",
- schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME ,
- ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam(
- value = "assetType") final String assetType,
- @Parameter(hidden = true) String jsonChangeInfo) {
-
- Response response = null;
-
- init();
-
- String requestURI = request.getRequestURI();
- String url = request.getMethod() + " " + requestURI;
- log.debug("Start handle request of {}", url);
-
- //get the business logic
- ServletContext context = request.getSession().getServletContext();
-
- Wrapper<ResponseFormat> responseWrapper = runValidations(assetType);
- ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
- Component component = null;
- Component responseObject = null;
- User modifier = null;
-
- try{
- // Validate X-ECOMP-InstanceID Header
- if (responseWrapper.isEmpty()) {
- validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
- }
-
- if (responseWrapper.isEmpty()) {
- //get user
- Either<User, ResponseFormat> eitherGetUser = getUser(request, userId);
- if (eitherGetUser.isRight()) {
- ResponseFormat responseFormat = eitherGetUser.right().value();
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
- modifier = eitherGetUser.left().value();
-
- //get the component id from the uuid
- Either<Component, ResponseFormat> latestVersion = lifecycleBusinessLogic.getLatestComponentByUuid(componentType, uuid);
- if (latestVersion.isRight()) {
- ResponseFormat responseFormat = latestVersion.right().value();
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
- component = latestVersion.left().value();
- String componentId = component.getUniqueId();
-
- //validate the transition is valid
- Either<LifeCycleTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(lifecycleTransition, modifier);
- if (validateEnum.isRight()) {
- ResponseFormat responseFormat = validateEnum.right().value();
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
- LifeCycleTransitionEnum transitionEnum = validateEnum.left().value();
-
- //create changeInfo
- LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction();
- try {
- if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) {
- ObjectMapper mapper = new ObjectMapper();
- changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks());
- }
- }
- catch (IOException e) {
- BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
- log.debug("failed to convert from json {}", jsonChangeInfo, e);
- ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(modifier, componentId, AuditingActionEnum.CHECKOUT_RESOURCE);
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
-
- //execute business logic
- Either<? extends Component, ResponseFormat> actionResponse = lifecycleBusinessLogic
- .changeComponentState(componentType, componentId, modifier, transitionEnum, changeInfo, false, true);
- if (actionResponse.isRight()) {
- log.info("failed to change resource state");
- ResponseFormat responseFormat = actionResponse.right().value();
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
-
- log.debug("change state successful !!!");
- responseObject = actionResponse.left().value();
- response = buildCreatedResourceResponse(responseObject, context, responseWrapper);
- } else {
- response = buildErrorResponse(responseWrapper.getInnerElement());
- }
-
- return response;
- } catch (IOException e) {
- BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State");
- log.debug("change lifecycle state failed with exception", e);
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- } catch (ComponentException e){
- ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
- responseWrapper.setInnerElement(responseFormat);
- return buildErrorResponse(responseFormat);
- }
- finally{
- getComponentsUtils().auditChangeLifecycleAction(responseWrapper.getInnerElement(), componentType, requestId,
- component, responseObject, new DistributionData(instanceIdHeader, requestURI), modifier);
- }
- }
-
- private Response buildCreatedResourceResponse(Component resource, ServletContext context,
- Wrapper<ResponseFormat> responseWrapper) throws IOException {
- ResponseFormat responseFormat;
- Response response;
- Either<? extends AssetMetadata, ResponseFormat> resMetadata = assetMetadataUtils
- .convertToSingleAssetMetadata(resource, request.getRequestURL().toString(),
- true);
- if (resMetadata.isRight()) {
- log.debug("Asset conversion Failed");
- responseFormat = resMetadata.right().value();
- responseWrapper.setInnerElement(responseFormat);
- response = buildErrorResponse(responseFormat);
- }else{
- final AssetMetadata assetData = resMetadata.left().value();
- assetData.setToscaModelURL(null);
-
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED));
- Object representation = RepresentationUtils.toRepresentation(assetData);
- response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
- }
- return response;
- }
-
- private void handleCategories(ServletContext context, String data, Resource resource,
- Wrapper<ResponseFormat> responseWrapper) {
- try {
- JSONParser parser = new JSONParser();
- JSONObject jsonObj = (JSONObject) parser.parse(data);
- String category = (String) jsonObj.get(CategoryTypeEnum.CATEGORY.getValue());
- String subcategory = (String) jsonObj.get(CategoryTypeEnum.SUBCATEGORY.getValue());
- if (Strings.isEmpty(category)) {
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
- ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
- }
- else if (Strings.isEmpty(subcategory)) {
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
- ActionStatus.COMPONENT_MISSING_SUBCATEGORY));
- }
- if (responseWrapper.isEmpty()) {
- // get All Categories
- Either<List<CategoryDefinition>, ActionStatus> allResourceCategories = elementBusinessLogic
- .getAllResourceCategories();
- // Error fetching categories
- if (allResourceCategories.isRight()) {
- responseWrapper.setInnerElement(
- getComponentsUtils().getResponseFormat(allResourceCategories.right().value()));
- } else {
- addCategories(resource, category, subcategory, allResourceCategories, responseWrapper);
- }
- }
- } catch (ParseException e) {
- log.debug("Exception occured in addCategories: {}", e.getMessage(), e);
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
- }
-
- }
-
- private void addCategories(Resource resource, String category, String subcategory,
- Either<List<CategoryDefinition>, ActionStatus> allResourceCategories,
- Wrapper<ResponseFormat> responseWrapper) {
- Optional<CategoryDefinition> optionalCategory =
- // Stream of all the categories
- allResourceCategories.left().value().stream()
- // filter in only relevant category
- .filter(e -> e.getName().equals(category))
- // get the result
- .findAny();
- if (!optionalCategory.isPresent()) {
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
- ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
- } else {
- CategoryDefinition categoryDefinition = optionalCategory.get();
-
- List<SubCategoryDefinition> subCaregories =
- // Stream of all sub-categories of the relevant
- // category
- categoryDefinition.getSubcategories().stream()
- // filter in only relevant sub-category
- .filter(e -> e.getName().equals(subcategory))
- // get the result
- .collect(Collectors.toList());
-
- if( subCaregories.isEmpty() ){
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
- ActionStatus.COMPONENT_INVALID_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
- }
- else{
- categoryDefinition.setSubcategories(subCaregories);
- resource.setCategories(Arrays.asList(categoryDefinition));
- }
-
- }
- }
-
-
-
-
-
-
- private Wrapper<ResponseFormat> runValidations(final String assetType) {
- Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
-
- // Validate X-ECOMP-InstanceID Header
- if (responseWrapper.isEmpty()) {
- String instanceId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER);
- validateXECOMPInstanceIDHeader(instanceId,responseWrapper);
- }
- // Validate USER_ID Header
- if (responseWrapper.isEmpty()) {
- validateHttpCspUserIdHeader(request.getHeader(Constants.USER_ID_HEADER),responseWrapper);
- }
- // Validate assetType
- if (responseWrapper.isEmpty()) {
- if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) && !AssetTypeEnum.SERVICES.getValue().equals(assetType)){
- responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
- }
- }
-
- return responseWrapper;
- }
-
- private Either<LifeCycleTransitionEnum, ResponseFormat> validateTransitionEnum(final String lifecycleTransition, User user) {
- LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT;
- try {
- transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition);
- } catch (IllegalArgumentException e) {
- log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString(), e);
- ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, "", AuditingActionEnum.CHECKOUT_RESOURCE);
- return Either.right(error);
- }
- return Either.left(transitionEnum);
- }
-
-}
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.jcabi.aspects.Loggable;
+import fj.data.Either;
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.info.Info;
+import io.swagger.v3.oas.annotations.media.ArraySchema;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.media.Schema;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.responses.ApiResponses;
+import org.apache.commons.lang3.StringUtils;
+import org.elasticsearch.common.Strings;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
+import org.openecomp.sdc.be.components.impl.ResourceImportManager;
+import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
+import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase;
+import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction;
+import org.openecomp.sdc.be.config.BeEcompErrorManager;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum;
+import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ExternalCategoryTypeEnum;
+import org.openecomp.sdc.be.ecomp.converters.AssetMetadataConverter;
+import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata;
+import org.openecomp.sdc.be.impl.ComponentsUtils;
+import org.openecomp.sdc.be.impl.ServletUtils;
+import org.openecomp.sdc.be.model.Resource;
+import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.Component;
+import org.openecomp.sdc.be.model.LifeCycleTransitionEnum;
+import org.openecomp.sdc.be.model.category.CategoryDefinition;
+import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
+import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
+import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
+import org.openecomp.sdc.be.servlets.RepresentationUtils;
+import org.openecomp.sdc.be.user.UserBusinessLogic;
+import org.openecomp.sdc.be.utils.CommonBeUtils;
+import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.datastructure.Wrapper;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+import org.openecomp.sdc.common.util.ValidationUtils;
+import org.openecomp.sdc.exception.ResponseFormat;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.Path;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.Produces;
+import javax.ws.rs.POST;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@Loggable(prepend = true, value = Loggable.DEBUG, trim = false)
+@Path("/v1/catalog")
+@OpenAPIDefinition(info = @Info(title = "CRUD External Servlet",
+ description = "This Servlet serves external users for creating assets and changing their lifecycle state"))
+
+@Singleton
+public class CrudExternalServlet extends AbstractValidationsServlet {
+
+ @Context
+ private HttpServletRequest request;
+
+ private static final Logger log = Logger.getLogger(CrudExternalServlet.class);
+ private final ElementBusinessLogic elementBusinessLogic;
+ private final AssetMetadataConverter assetMetadataUtils;
+ private final LifecycleBusinessLogic lifecycleBusinessLogic;
+ private final ResourceBusinessLogic resourceBusinessLogic;
+ private final ServiceBusinessLogic serviceBusinessLogic;
+
+ @Inject
+ public CrudExternalServlet(UserBusinessLogic userBusinessLogic,
+ ComponentInstanceBusinessLogic componentInstanceBL,
+ ComponentsUtils componentsUtils, ServletUtils servletUtils,
+ ResourceImportManager resourceImportManager,
+ ElementBusinessLogic elementBusinessLogic,
+ AssetMetadataConverter assetMetadataUtils,
+ LifecycleBusinessLogic lifecycleBusinessLogic,
+ ResourceBusinessLogic resourceBusinessLogic,
+ ServiceBusinessLogic serviceBusinessLogic) {
+ super(userBusinessLogic, componentInstanceBL, componentsUtils, servletUtils, resourceImportManager);
+ this.elementBusinessLogic = elementBusinessLogic;
+ this.assetMetadataUtils = assetMetadataUtils;
+ this.lifecycleBusinessLogic = lifecycleBusinessLogic;
+ this.resourceBusinessLogic = resourceBusinessLogic;
+ this.serviceBusinessLogic = serviceBusinessLogic;
+ }
+
+ /**
+ * Creates a new Asset (Resource or Service)
+ *
+ * @param assetType
+ * @param data
+ * @param userId
+ * @param instanceIdHeader
+ * @return
+ */
+ @POST
+ @Path("/{assetType}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Operation(description = "creates an asset (resource or service)", method = "POST", summary = "Creates an asset (resource or service)")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "ECOMP component is authenticated and Asset created",
+ content = @Content(array = @ArraySchema(schema = @Schema(implementation = Resource.class)))),
+ @ApiResponse(responseCode = "400", description = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
+ @ApiResponse(responseCode = "401",
+ description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
+ @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
+ @ApiResponse(responseCode = "404",
+ description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
+ @ApiResponse(responseCode = "405",
+ description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
+ @ApiResponse(responseCode = "500",
+ description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
+ @ApiResponse(responseCode = "400",
+ description = "The name provided for the newly created resource is already in use for another resource in SDC - SVC4050"),
+ @ApiResponse(responseCode = "400",
+ description = "Invalid field format. One of the provided fields does not comply with the field rules - SVC4126"),
+ @ApiResponse(responseCode = "400",
+ description = "Missing request body. The post request did not contain the expected body - SVC4500"),
+ @ApiResponse(responseCode = "400",
+ description = "The resource name is missing in the request body - SVC4062"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT description has wrong format - SVC4064"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT description has wrong format (exceeds limit) - SVC4065"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT tags exceeds character limit - SVC4066"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT vendor name exceeds character limit - SVC4067"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT vendor release exceeds character limit - SVC4068"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT ATT Contact has wrong format - SVC4069"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT name has wrong format - SVC4070"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT vendor name has wrong format - SVC4071"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT vendor release has wrong format - SVC4072"),
+ @ApiResponse(responseCode = "400",
+ description = "Create VFCMT request: VFCMT name exceeds character limit - SVC4073"),
+ @ApiResponse(responseCode = "400", description = "Invalid Content. Missing PROJECT_CODE number - SVC4129"),
+ @ApiResponse(responseCode = "409", description = "Error: %1 (Service) with name '%2' already exists. - SVC4050")})
+ // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType =
+ // "org.openecomp.sdc.be.model.Resource", paramType = "body", value = "json describe the created
+ // resource")})
+ public Response createComponentExternal(
+ @Parameter(description = "Determines the format of the body of the request",
+ required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
+ @Parameter(description = "The user id",
+ required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
+ @Parameter(description = "X-ECOMP-RequestID header",
+ required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
+ @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
+ value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
+ @Parameter(description = "Determines the format of the body of the response",
+ required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
+ @Parameter(description = "The username and password",
+ required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
+ @Parameter(description = "The requested asset type", required = true,
+ schema = @Schema(
+ allowableValues = {"resources, services"})) @PathParam("assetType") final String assetType,
+ @Parameter(hidden = true) String data) {
+
+ init();
+
+ Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
+ String requestURI = request.getRequestURI();
+ String url = request.getMethod() + " " + requestURI;
+ log.debug("Start handle request of {}", url);
+ Resource resource = null;
+ User modifier = null;
+ ResourceCommonInfo resourceCommonInfo = new ResourceCommonInfo(ComponentTypeEnum.RESOURCE.getValue());
+ Service service = null;
+
+ ServletContext context = request.getSession().getServletContext();
+ try {
+ // Validate X-ECOMP-InstanceID Header
+ if (responseWrapper.isEmpty()) {
+ validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
+ }
+ // Validate USER_ID Header
+ if (responseWrapper.isEmpty()) {
+ validateHttpCspUserIdHeader(userId, responseWrapper);
+ }
+ // Validate assetType
+
+ if( responseWrapper.isEmpty() && !(AssetTypeEnum.RESOURCES.getValue().equals(assetType) || AssetTypeEnum.SERVICES.getValue().equals(assetType))) {
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
+ }
+
+ if (responseWrapper.isEmpty() && AssetTypeEnum.SERVICES.getValue().equals(assetType)) {
+
+ modifier = new User();
+ modifier.setUserId(userId);
+ Either<Service, ResponseFormat> convertResponse = getComponentsUtils()
+ .convertJsonToObjectUsingObjectMapper(data, modifier, Service.class,
+ null, ComponentTypeEnum.SERVICE);
+ if( convertResponse.isRight() ){
+ responseWrapper.setInnerElement(convertResponse.right().value());
+ }
+ else{
+ service = convertResponse.left().value();
+ }
+
+ if (service==null){
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.SERVICE_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue()));
+ }
+
+ //validate name exist
+ if(responseWrapper.isEmpty() && Strings.isEmpty(service.getName())){
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.SERVICE.getValue()));
+ }
+
+ //validate category
+ if(responseWrapper.isEmpty() && service.getCategories().size()>0 && !ExternalCategoryTypeEnum.containsIgnoreCase(service.getCategories().get(0).getName())){
+ log.debug("Service category is not supported {}", service.getCategories().get(0).getName());
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue()));
+ }
+
+ if(responseWrapper.isEmpty()){
+ service.setSystemName(ValidationUtils.convertToSystemName(service.getName()));
+ log.debug("Service system name :"+service.getSystemName());
+ }
+
+ if(responseWrapper.isEmpty()){
+ Either<Service, ResponseFormat> actionResponse = serviceBusinessLogic.createService(service, modifier);
+ if (actionResponse.isRight()) {
+ log.debug("Failed to create service");
+ responseWrapper.setInnerElement(actionResponse.right().value());
+ return buildErrorResponse(responseWrapper.getInnerElement());
+ }
+
+ // Create the service in the dataModel
+ service = actionResponse.left().value();
+ Object result = RepresentationUtils.toRepresentation(actionResponse.left().value());
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED));
+ return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result);
+ }
+ else{
+ return buildErrorResponse(responseWrapper.getInnerElement());
+ }
+
+
+
+ } else {
+ //Validate resource type
+ if(responseWrapper.isEmpty()){
+ JSONParser parser = new JSONParser();
+ JSONObject jsonObj = (JSONObject) parser.parse(data);
+ String resourceType = (String) jsonObj.get(FilterKeyEnum.RESOURCE_TYPE.getName());
+ if( StringUtils.isEmpty(resourceType) || !ResourceTypeEnum.containsName(resourceType) ){
+ resourceCommonInfo.setResourceName((String) jsonObj.get("name"));
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT));
+ }
+ }
+ // Convert the user json to a resource
+ if (responseWrapper.isEmpty()) {
+ modifier = new User();
+ modifier.setUserId(userId);
+ Either<Resource, ResponseFormat> eitherResource = getComponentsUtils()
+ .convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class,
+ null, ComponentTypeEnum.RESOURCE);
+ if( eitherResource.isRight() ){
+ responseWrapper.setInnerElement(eitherResource.right().value());
+ }
+ else{
+ resource = eitherResource.left().value();
+ }
+
+ }
+ //validate name exist
+ if(responseWrapper.isEmpty()){
+ if( Strings.isEmpty(resource.getName())){
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue()));
+
+ }
+ }
+
+ if(responseWrapper.isEmpty()){
+ resource.setDerivedFrom(Arrays.asList("tosca.nodes.Root"));
+ resource.setSystemName(ValidationUtils.convertToSystemName(resource.getName()));
+ resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VFCMT.name(),
+ resource.getSystemName()));
+ handleCategories(context, data, resource, responseWrapper);
+ }
+ // Create the resource in the dataModel
+ if (responseWrapper.isEmpty()) {
+ resource = resourceBusinessLogic.createResource(resource, null,
+ modifier, null, null);
+ return buildCreatedResourceResponse(resource, context, responseWrapper);
+ } else {
+ return buildErrorResponse(responseWrapper.getInnerElement());
+ }
+ }
+
+ } catch (IOException|ParseException e) {
+ final String message = "failed to create vfc monitoring template resource";
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message);
+ log.debug(message, e);
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ return buildErrorResponse(responseWrapper.getInnerElement());
+ } catch (ComponentException e){
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+ finally {
+ if(AssetTypeEnum.RESOURCES.getValue().equals(assetType)) {
+ getComponentsUtils().auditCreateResourceExternalApi(responseWrapper.getInnerElement(), resourceCommonInfo, request, resource);
+ } else if(AssetTypeEnum.SERVICES.getValue().equals(assetType)) {
+ getComponentsUtils().auditCreateServiceExternalApi(responseWrapper.getInnerElement(), request, service);
+ }
+ }
+ }
+
+ /**
+ * Changing the lifecycle of an asset
+ * @param jsonChangeInfo The description - request body
+ * @param assetType The requested asset type.Valid values are: resources / services (for VFCMT – use "resources")
+ * @param uuid The uuid of the desired resource to be changed
+ * @param lifecycleTransition The lifecycle operation to be performed on the asset.Valid values are:Checkin / Checkout / CERTIFICATION_REQUEST
+ * @param userId
+ * @return
+ */
+ @POST
+ @Path("/{assetType}/{uuid}/lifecycleState/{lifecycleOperation}")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Operation(description = "Change Resource lifecycle State", method = "POST")
+ @ApiResponses(value = {
+ @ApiResponse(responseCode = "200", description = "Resource state changed",
+ content = @Content(array = @ArraySchema(schema = @Schema(implementation = AssetMetadata.class)))),
+ @ApiResponse(responseCode = "400", description = "Missing X-ECOMP-InstanceID HTTP header - POL5001"),
+ @ApiResponse(responseCode = "401",
+ description = "ECOMP component should authenticate itself and to re-send again HTTP request with its Basic Authentication credentials - POL5002"),
+ @ApiResponse(responseCode = "403", description = "ECOMP component is not authorized - POL5003"),
+ @ApiResponse(responseCode = "404",
+ description = "Error: Requested '%1' (uuid) resource was not found - SVC4063"),
+ @ApiResponse(responseCode = "405",
+ description = "Method Not Allowed : Invalid HTTP method type used ( PUT,DELETE,POST will be rejected) - POL4050"),
+ @ApiResponse(responseCode = "500",
+ description = "The GET request failed either due to internal SDC problem. ECOMP Component should continue the attempts to get the needed information - POL5000"),
+ @ApiResponse(responseCode = "403", description = "Asset is already checked-out by another user - SVC4085"),
+ @ApiResponse(responseCode = "403",
+ description = "Asset is being edited by different user. Only one user can checkout and edit an asset on given time. The asset will be available for checkout after the other user will checkin the asset - SVC4080")})
+ // @ApiImplicitParams({@ApiImplicitParam(required = true, dataType = "org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction", paramType = "body", value = "userRemarks - Short description (free text) about the asset version being changed")})
+ public Response changeResourceStateExternal(
+ @Parameter(description = "Determines the format of the body of the request",
+ required = true) @HeaderParam(value = Constants.CONTENT_TYPE_HEADER) String contentType,
+ @Parameter(description = "The user id",
+ required = true) @HeaderParam(value = Constants.USER_ID_HEADER) final String userId,
+ @Parameter(description = "X-ECOMP-RequestID header",
+ required = false) @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId,
+ @Parameter(description = "X-ECOMP-InstanceID header", required = true) @HeaderParam(
+ value = Constants.X_ECOMP_INSTANCE_ID_HEADER) final String instanceIdHeader,
+ @Parameter(description = "Determines the format of the body of the response",
+ required = false) @HeaderParam(value = Constants.ACCEPT_HEADER) String accept,
+ @Parameter(description = "The username and password",
+ required = true) @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization,
+ @Parameter(schema = @Schema(allowableValues = {"checkout, checkin"}),
+ required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition,
+ @Parameter(description = "id of component to be changed") @PathParam(value = "uuid") final String uuid,
+ @Parameter(description = "validValues: resources / services ",
+ schema = @Schema(allowableValues = {ComponentTypeEnum.RESOURCE_PARAM_NAME ,
+ ComponentTypeEnum.SERVICE_PARAM_NAME})) @PathParam(
+ value = "assetType") final String assetType,
+ @Parameter(hidden = true) String jsonChangeInfo) {
+
+ Response response = null;
+
+ init();
+
+ String requestURI = request.getRequestURI();
+ String url = request.getMethod() + " " + requestURI;
+ log.debug("Start handle request of {}", url);
+
+ //get the business logic
+ ServletContext context = request.getSession().getServletContext();
+
+ Wrapper<ResponseFormat> responseWrapper = runValidations(assetType);
+ ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType);
+ Component component = null;
+ Component responseObject = null;
+ User modifier = null;
+
+ try{
+ // Validate X-ECOMP-InstanceID Header
+ if (responseWrapper.isEmpty()) {
+ validateXECOMPInstanceIDHeader(instanceIdHeader, responseWrapper);
+ }
+
+ if (responseWrapper.isEmpty()) {
+ //get user
+ Either<User, ResponseFormat> eitherGetUser = getUser(request, userId);
+ if (eitherGetUser.isRight()) {
+ ResponseFormat responseFormat = eitherGetUser.right().value();
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+ modifier = eitherGetUser.left().value();
+
+ //get the component id from the uuid
+ Either<Component, ResponseFormat> latestVersion = lifecycleBusinessLogic.getLatestComponentByUuid(componentType, uuid);
+ if (latestVersion.isRight()) {
+ ResponseFormat responseFormat = latestVersion.right().value();
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+ component = latestVersion.left().value();
+ String componentId = component.getUniqueId();
+
+ //validate the transition is valid
+ Either<LifeCycleTransitionEnum, ResponseFormat> validateEnum = validateTransitionEnum(lifecycleTransition, modifier);
+ if (validateEnum.isRight()) {
+ ResponseFormat responseFormat = validateEnum.right().value();
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+ LifeCycleTransitionEnum transitionEnum = validateEnum.left().value();
+
+ //create changeInfo
+ LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction();
+ try {
+ if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) {
+ ObjectMapper mapper = new ObjectMapper();
+ changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks());
+ }
+ }
+ catch (IOException e) {
+ BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject");
+ log.debug("failed to convert from json {}", jsonChangeInfo, e);
+ ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(modifier, componentId, AuditingActionEnum.CHECKOUT_RESOURCE);
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+
+ //execute business logic
+ Either<? extends Component, ResponseFormat> actionResponse = lifecycleBusinessLogic
+ .changeComponentState(componentType, componentId, modifier, transitionEnum, changeInfo, false, true);
+ if (actionResponse.isRight()) {
+ log.info("failed to change resource state");
+ ResponseFormat responseFormat = actionResponse.right().value();
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+
+ log.debug("change state successful !!!");
+ responseObject = actionResponse.left().value();
+ response = buildCreatedResourceResponse(responseObject, context, responseWrapper);
+ } else {
+ response = buildErrorResponse(responseWrapper.getInnerElement());
+ }
+
+ return response;
+ } catch (IOException e) {
+ BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State");
+ log.debug("change lifecycle state failed with exception", e);
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR);
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ } catch (ComponentException e){
+ ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(e);
+ responseWrapper.setInnerElement(responseFormat);
+ return buildErrorResponse(responseFormat);
+ }
+ finally{
+ getComponentsUtils().auditChangeLifecycleAction(responseWrapper.getInnerElement(), componentType, requestId,
+ component, responseObject, new DistributionData(instanceIdHeader, requestURI), modifier);
+ }
+ }
+
+ private Response buildCreatedResourceResponse(Component resource, ServletContext context,
+ Wrapper<ResponseFormat> responseWrapper) throws IOException {
+ ResponseFormat responseFormat;
+ Response response;
+ Either<? extends AssetMetadata, ResponseFormat> resMetadata = assetMetadataUtils
+ .convertToSingleAssetMetadata(resource, request.getRequestURL().toString(),
+ true);
+ if (resMetadata.isRight()) {
+ log.debug("Asset conversion Failed");
+ responseFormat = resMetadata.right().value();
+ responseWrapper.setInnerElement(responseFormat);
+ response = buildErrorResponse(responseFormat);
+ }else{
+ final AssetMetadata assetData = resMetadata.left().value();
+ assetData.setToscaModelURL(null);
+
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.CREATED));
+ Object representation = RepresentationUtils.toRepresentation(assetData);
+ response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation);
+ }
+ return response;
+ }
+
+ private void handleCategories(ServletContext context, String data, Resource resource,
+ Wrapper<ResponseFormat> responseWrapper) {
+ try {
+ JSONParser parser = new JSONParser();
+ JSONObject jsonObj = (JSONObject) parser.parse(data);
+ String category = (String) jsonObj.get(CategoryTypeEnum.CATEGORY.getValue());
+ String subcategory = (String) jsonObj.get(CategoryTypeEnum.SUBCATEGORY.getValue());
+ if (Strings.isEmpty(category)) {
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
+ }
+ else if (Strings.isEmpty(subcategory)) {
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.COMPONENT_MISSING_SUBCATEGORY));
+ }
+ if (responseWrapper.isEmpty()) {
+ // get All Categories
+ Either<List<CategoryDefinition>, ActionStatus> allResourceCategories = elementBusinessLogic
+ .getAllResourceCategories();
+ // Error fetching categories
+ if (allResourceCategories.isRight()) {
+ responseWrapper.setInnerElement(
+ getComponentsUtils().getResponseFormat(allResourceCategories.right().value()));
+ } else {
+ addCategories(resource, category, subcategory, allResourceCategories, responseWrapper);
+ }
+ }
+ } catch (ParseException e) {
+ log.debug("Exception occured in addCategories: {}", e.getMessage(), e);
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+ }
+
+ }
+
+ private void addCategories(Resource resource, String category, String subcategory,
+ Either<List<CategoryDefinition>, ActionStatus> allResourceCategories,
+ Wrapper<ResponseFormat> responseWrapper) {
+ Optional<CategoryDefinition> optionalCategory =
+ // Stream of all the categories
+ allResourceCategories.left().value().stream()
+ // filter in only relevant category
+ .filter(e -> e.getName().equals(category))
+ // get the result
+ .findAny();
+ if (!optionalCategory.isPresent()) {
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
+ } else {
+ CategoryDefinition categoryDefinition = optionalCategory.get();
+
+ List<SubCategoryDefinition> subCaregories =
+ // Stream of all sub-categories of the relevant
+ // category
+ categoryDefinition.getSubcategories().stream()
+ // filter in only relevant sub-category
+ .filter(e -> e.getName().equals(subcategory))
+ // get the result
+ .collect(Collectors.toList());
+
+ if( subCaregories.isEmpty() ){
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(
+ ActionStatus.COMPONENT_INVALID_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue()));
+ }
+ else{
+ categoryDefinition.setSubcategories(subCaregories);
+ resource.setCategories(Arrays.asList(categoryDefinition));
+ }
+
+ }
+ }
+
+ private Wrapper<ResponseFormat> runValidations(final String assetType) {
+ Wrapper<ResponseFormat> responseWrapper = new Wrapper<>();
+
+ // Validate X-ECOMP-InstanceID Header
+ if (responseWrapper.isEmpty()) {
+ String instanceId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER);
+ validateXECOMPInstanceIDHeader(instanceId,responseWrapper);
+ }
+ // Validate USER_ID Header
+ if (responseWrapper.isEmpty()) {
+ validateHttpCspUserIdHeader(request.getHeader(Constants.USER_ID_HEADER),responseWrapper);
+ }
+ // Validate assetType
+ if (responseWrapper.isEmpty()) {
+ if( !AssetTypeEnum.RESOURCES.getValue().equals(assetType) && !AssetTypeEnum.SERVICES.getValue().equals(assetType)){
+ responseWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
+ }
+ }
+
+ return responseWrapper;
+ }
+
+ private Either<LifeCycleTransitionEnum, ResponseFormat> validateTransitionEnum(final String lifecycleTransition, User user) {
+ LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT;
+ try {
+ transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition);
+ } catch (IllegalArgumentException e) {
+ log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString(), e);
+ ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, "", AuditingActionEnum.CHECKOUT_RESOURCE);
+ return Either.right(error);
+ }
+ return Either.left(transitionEnum);
+ }
+
+}
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
index 3c3a3dbef7..59e4c2e78c 100644
--- a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
+++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java
@@ -612,6 +612,34 @@ public class ComponentsUtils {
getAuditingManager().auditEvent(factory);
}
+
+ public void auditCreateServiceExternalApi(ResponseFormat responseFormat, HttpServletRequest request, Component service) {
+
+ String invariantUuid = null;
+ String serviceInstanceId = null;
+
+ User modifier = new User();
+ modifier.setUserId(request.getHeader(Constants.USER_ID_HEADER));
+ DistributionData distributionData = new DistributionData(request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER), request.getRequestURI());
+ String requestId = request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER);
+
+ if(null != service) {
+ invariantUuid = service.getInvariantUUID();
+ serviceInstanceId = service.getUUID();
+ }
+
+ AuditEventFactory factory = new AuditCreateServiceExternalApiEventFactory(
+ CommonAuditData.newBuilder()
+ .status(responseFormat.getStatus())
+ .description(getMessageString(responseFormat))
+ .requestId(requestId)
+ .serviceInstanceId(serviceInstanceId)
+ .build(),
+ new ResourceCommonInfo(ComponentTypeEnum.SERVICE.name()), distributionData, invariantUuid, modifier);
+
+ getAuditingManager().auditEvent(factory);
+
+ }
public void auditExternalActivateService(ResponseFormat responseFormat, DistributionData distributionData, String requestId, String serviceInstanceUuid, User modifier) {
AuditEventFactory factory = new AuditActivateServiceExternalApiEventFactory(
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/AuditTestUtils.java b/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/AuditTestUtils.java
index f08db3799b..9178900142 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/AuditTestUtils.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/AuditTestUtils.java
@@ -242,6 +242,13 @@ public class AuditTestUtils {
"\" CURR_STATE = \"" + CURRENT_STATE + "\" CURR_ARTIFACT_UUID = \"" + ARTIFACT_UUID + "\" STATUS = \"" + STATUS_OK +
"\" SERVICE_INSTANCE_ID = \"" + SERVICE_INSTANCE_ID + "\" INVARIANT_UUID = \"" + INVARIANT_UUID + "\" DESC = \"" + DESCRIPTION + "\"";
+ public final static String EXPECTED_EXTERNAL_CREATE_SERVICE_LOG_STR = "ACTION = \"" + AuditingActionEnum.CREATE_SERVICE_BY_API.getName() +
+ "\" RESOURCE_TYPE = \"" + RESOURCE_TYPE + "\" CONSUMER_ID = \"" + DIST_CONSUMER_ID +
+ "\" RESOURCE_URL = \"" + DIST_RESOURCE_URL + "\" MODIFIER = \"" + MODIFIER_UID +
+ "\" STATUS = \"" + STATUS_OK + "\" SERVICE_INSTANCE_ID = \"" + SERVICE_INSTANCE_ID +
+ "\" INVARIANT_UUID = \"" + INVARIANT_UUID + "\" DESC = \"" + DESCRIPTION + "\"";
+
+
public static User user;
public static User modifier;
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactoryTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactoryTest.java
new file mode 100644
index 0000000000..71160eda8e
--- /dev/null
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/auditing/impl/externalapi/AuditCreateServiceExternalApiEventFactoryTest.java
@@ -0,0 +1,131 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Telstra 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.openecomp.sdc.be.auditing.impl.externalapi;
+
+import org.junit.Before;
+import org.junit.Test;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.openecomp.sdc.be.auditing.impl.AuditTestUtils.*;
+
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.openecomp.sdc.be.auditing.api.AuditEventFactory;
+import org.openecomp.sdc.be.auditing.impl.AuditingManager;
+import org.openecomp.sdc.be.config.Configuration;
+import org.openecomp.sdc.be.dao.api.ActionStatus;
+import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao;
+import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
+import org.openecomp.sdc.be.dao.impl.AuditingDao;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
+import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent;
+import org.openecomp.sdc.be.resources.data.auditing.ExternalApiEvent;
+import org.openecomp.sdc.be.resources.data.auditing.model.CommonAuditData;
+import org.openecomp.sdc.be.resources.data.auditing.model.DistributionData;
+import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo;
+import org.openecomp.sdc.test.utils.TestConfigurationProvider;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditCreateServiceExternalApiEventFactoryTest {
+
+ private AuditCreateServiceExternalApiEventFactory createTestSubject() {
+ CommonAuditData.Builder newBuilder = CommonAuditData.newBuilder()
+ .description(DESCRIPTION)
+ .status(STATUS_OK)
+ .requestId(REQUEST_ID)
+ .serviceInstanceId(SERVICE_INSTANCE_ID);
+ CommonAuditData commonAuData = newBuilder.build();
+ return new AuditCreateServiceExternalApiEventFactory(commonAuData,
+ new ResourceCommonInfo(RESOURCE_TYPE),
+ new DistributionData(DIST_CONSUMER_ID,DIST_RESOURCE_URL),INVARIANT_UUID,
+ modifier);
+ }
+
+ private AuditingManager auditingManager;
+
+ @Mock
+ private static AuditCassandraDao cassandraDao;
+ @Mock
+ private static AuditingDao auditingDao;
+ @Mock
+ private static Configuration.ElasticSearchConfig esConfig;
+
+ @Captor
+ private ArgumentCaptor<ExternalApiEvent> eventCaptor;
+
+ @Before
+ public void setUp() {
+ init(esConfig);
+ auditingManager = new AuditingManager(auditingDao, cassandraDao, new TestConfigurationProvider());
+ }
+
+ @Test
+ public void testGetLogMessage() throws Exception {
+ AuditCreateServiceExternalApiEventFactory testSubject;
+
+ // default test
+ testSubject = createTestSubject();
+ testSubject.getLogMessage();
+ assertThat(testSubject.getLogMessage()).isNotBlank();
+ assertThat(testSubject.getLogMessage()).isEqualTo(EXPECTED_EXTERNAL_CREATE_SERVICE_LOG_STR);
+
+ }
+
+ @Test
+ public void testCreateServiceEvent() {
+ AuditEventFactory factory = new AuditCreateServiceExternalApiEventFactory(
+ CommonAuditData.newBuilder()
+ .description(DESCRIPTION)
+ .status(STATUS_OK)
+ .requestId(REQUEST_ID)
+ .serviceInstanceId(SERVICE_INSTANCE_ID)
+ .build(),
+ new ResourceCommonInfo(RESOURCE_TYPE),
+ new DistributionData(DIST_CONSUMER_ID, DIST_RESOURCE_URL),
+ INVARIANT_UUID, modifier);
+
+ when(auditingDao.addRecord(any(AuditingGenericEvent.class), eq(AuditingActionEnum.CREATE_SERVICE_BY_API.getAuditingEsType())))
+ .thenReturn(ActionStatus.OK);
+ when(cassandraDao.saveRecord(any(AuditingGenericEvent.class))).thenReturn(CassandraOperationStatus.OK);
+
+ assertThat(auditingManager.auditEvent(factory)).isEqualTo(EXPECTED_EXTERNAL_CREATE_SERVICE_LOG_STR);
+ verifyExternalApiEvent(AuditingActionEnum.CREATE_SERVICE_BY_API.getName());
+ }
+
+ private void verifyExternalApiEvent(String action) {
+ verify(cassandraDao).saveRecord(eventCaptor.capture());
+ ExternalApiEvent storedEvent = eventCaptor.getValue();
+ assertThat(storedEvent.getModifier()).isEqualTo(MODIFIER_UID);
+ assertThat(storedEvent.getDesc()).isEqualTo(DESCRIPTION);
+ assertThat(storedEvent.getStatus()).isEqualTo(STATUS_OK);
+ assertThat(storedEvent.getServiceInstanceId()).isEqualTo(SERVICE_INSTANCE_ID);
+ assertThat(storedEvent.getAction()).isEqualTo(action);
+ assertThat(storedEvent.getResourceType()).isEqualTo(RESOURCE_TYPE);
+ }
+}
+
+
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentsUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentsUtilsTest.java
index 22247fc000..15166fc590 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentsUtilsTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentsUtilsTest.java
@@ -33,6 +33,7 @@ import org.openecomp.sdc.be.auditing.api.AuditEventFactory;
import org.openecomp.sdc.be.auditing.impl.AuditingManager;
import org.openecomp.sdc.be.auditing.impl.externalapi.AuditChangeLifecycleExternalApiEventFactory;
import org.openecomp.sdc.be.auditing.impl.externalapi.AuditCreateResourceExternalApiEventFactory;
+import org.openecomp.sdc.be.auditing.impl.externalapi.AuditCreateServiceExternalApiEventFactory;
import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
import org.openecomp.sdc.be.impl.ComponentsUtils;
import org.openecomp.sdc.be.model.*;
@@ -560,7 +561,7 @@ public class ComponentsUtilsTest {
when(request.getRequestURI()).thenReturn(DIST_RESOURCE_URL);
utils.auditCreateResourceExternalApi(responseFormat, new ResourceCommonInfo(RESOURCE_NAME, ComponentTypeEnum.RESOURCE.getValue()),
- request, null);
+ request, null);
verify(manager).auditEvent(factoryCaptor.capture());
AuditCreateResourceExternalApiEventFactory factory = (AuditCreateResourceExternalApiEventFactory)factoryCaptor.getValue();
@@ -638,6 +639,82 @@ public class ComponentsUtilsTest {
}
@Test
+ public void auditExternalCreateServiceEventWhenResourceObjectIsNull() {
+ when(responseFormat.getStatus()).thenReturn(Integer.valueOf(STATUS_500));
+ when(responseFormat.getFormattedMessage()).thenReturn(DESC_ERROR);
+
+ when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
+ when(request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER)).thenReturn(DIST_CONSUMER_ID);
+ when(request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER)).thenReturn(REQUEST_ID);
+ when(request.getRequestURI()).thenReturn(DIST_RESOURCE_URL);
+
+ utils.auditCreateServiceExternalApi(responseFormat, request, null);
+
+ verify(manager).auditEvent(factoryCaptor.capture());
+ AuditCreateServiceExternalApiEventFactory factory = (AuditCreateServiceExternalApiEventFactory)factoryCaptor.getValue();
+
+ ExternalApiEvent event = (ExternalApiEvent)factory.getDbEvent();
+ verifyCommonDataForExternalApiEvent(event, false);
+ verifyPreviousResourceVersionInfoForExternalApiEvent(event, true);
+ verifyCurrentResourceVersionInfoForExternalApiEvent(event, true);
+ verifyDistributionDataForExternalApiEvent(event);
+ assertThat(event.getModifier()).isEqualTo("(" + USER_ID + ")");
+ assertThat(event.getInvariantUuid()).isNull();
+ }
+
+ @Test
+ public void auditExternalCreateServiceEventWhenResourceObjectIsNullAndRequestDataIsNotProvided() {
+ when(responseFormat.getStatus()).thenReturn(Integer.valueOf(STATUS_500));
+ when(responseFormat.getFormattedMessage()).thenReturn(DESC_ERROR);
+
+ when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(null);
+ when(request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER)).thenReturn(null);
+ when(request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER)).thenReturn(REQUEST_ID);
+ when(request.getRequestURI()).thenReturn(null);
+
+ utils.auditCreateServiceExternalApi(responseFormat, request, null);
+
+ verify(manager).auditEvent(factoryCaptor.capture());
+ AuditCreateServiceExternalApiEventFactory factory = (AuditCreateServiceExternalApiEventFactory)factoryCaptor.getValue();
+
+ ExternalApiEvent event = (ExternalApiEvent)factory.getDbEvent();
+ verifyCommonDataForExternalApiEvent(event, false);
+ verifyPreviousResourceVersionInfoForExternalApiEvent(event, true);
+ verifyCurrentResourceVersionInfoForExternalApiEvent(event, true);
+ verifyDistributionDataNotSetForExternalApiEvent(event);
+ assertThat(event.getModifier()).isEmpty();
+ assertThat(event.getInvariantUuid()).isNull();
+ }
+
+ @Test
+ public void auditExternalCreateServiceEventWhenResourceObjectAndRequestDataProvided() {
+ when(responseFormat.getStatus()).thenReturn(Integer.valueOf(STATUS_OK));
+ when(responseFormat.getFormattedMessage()).thenReturn(DESCRIPTION);
+
+ when(request.getHeader(Constants.USER_ID_HEADER)).thenReturn(USER_ID);
+ when(request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER)).thenReturn(DIST_CONSUMER_ID);
+ when(request.getHeader(Constants.X_ECOMP_REQUEST_ID_HEADER)).thenReturn(REQUEST_ID);
+ when(request.getRequestURI()).thenReturn(DIST_RESOURCE_URL);
+
+ Service service = new Service();
+ service.setInvariantUUID(INVARIANT_UUID);
+ service.setUUID(SERVICE_INSTANCE_ID);
+
+ utils.auditCreateServiceExternalApi(responseFormat, request, service);
+
+ verify(manager).auditEvent(factoryCaptor.capture());
+ AuditCreateServiceExternalApiEventFactory factory = (AuditCreateServiceExternalApiEventFactory)factoryCaptor.getValue();
+
+ ExternalApiEvent event = (ExternalApiEvent)factory.getDbEvent();
+ verifyCommonDataForExternalApiEvent(event, true);
+ verifyPreviousResourceVersionInfoForExternalApiEvent(event, true);
+ verifyDistributionDataForExternalApiEvent(event);
+ assertThat(event.getCurrArtifactUuid()).isNull();
+ assertThat(event.getModifier()).isEqualTo("(" + USER_ID + ")");
+ assertThat(event.getInvariantUuid()).isEqualTo(INVARIANT_UUID);
+ }
+
+ @Test
public void checkIfAuditEventIsExternal() {
assertThat(utils.isExternalApiEvent(AuditingActionEnum.ARTIFACT_UPLOAD_BY_API)).isTrue();
assertThat(utils.isExternalApiEvent(AuditingActionEnum.ARTIFACT_UPLOAD)).isFalse();
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServletTest.java
index 24f06b4543..9b4a98de01 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServletTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServletTest.java
@@ -37,6 +37,7 @@ import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic;
import org.openecomp.sdc.be.components.impl.ElementBusinessLogic;
import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic;
import org.openecomp.sdc.be.components.impl.ResourceImportManager;
+import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic;
import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic;
import org.openecomp.sdc.be.config.SpringConfig;
import org.openecomp.sdc.be.dao.api.ActionStatus;
@@ -72,25 +73,25 @@ import static org.mockito.Mockito.when;
public class AssetsDataServletTest extends JerseyTest {
- public static final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
- public static final HttpSession session = Mockito.mock(HttpSession.class);
- public static final ServletContext servletContext = Mockito.mock(ServletContext.class);
- public static final WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class);
- public static final WebApplicationContext webApplicationContext = Mockito.mock(WebApplicationContext.class);
- public static final ResponseFormat responseFormat = Mockito.mock(ResponseFormat.class);
- public static final ServletUtils servletUtils = Mockito.mock(ServletUtils.class);
- public static final ComponentsUtils componentsUtils = Mockito.mock(ComponentsUtils.class);
- public static final ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class);
- public static final ResourceBusinessLogic resourceBusinessLogic = Mockito.mock(ResourceBusinessLogic.class);
- public static final ElementBusinessLogic elementBusinessLogic = Mockito.mock(ElementBusinessLogic.class);
- public static final Resource resource = Mockito.mock(Resource.class);
- public static final CategoryDefinition categoryDefinition = Mockito.mock(CategoryDefinition.class);
- public static final SubCategoryDefinition subCategoryDefinition = Mockito.mock(SubCategoryDefinition.class);
- public static final AssetMetadataConverter assetMetadataConverter = Mockito.mock(AssetMetadataConverter.class);
- public static final ResourceAssetMetadata resourceAssetMetadata = new ResourceAssetMetadata();
- public static final UserBusinessLogic userBusinessLogic = Mockito.mock(UserBusinessLogic.class);
- public static final ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class);
- public static final LifecycleBusinessLogic lifecycleBusinessLogic = Mockito.mock(LifecycleBusinessLogic.class);
+ private static final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+ private static final HttpSession session = Mockito.mock(HttpSession.class);
+ private static final ServletContext servletContext = Mockito.mock(ServletContext.class);
+ private static final WebAppContextWrapper webAppContextWrapper = Mockito.mock(WebAppContextWrapper.class);
+ private static final WebApplicationContext webApplicationContext = Mockito.mock(WebApplicationContext.class);
+ private static final ServletUtils servletUtils = Mockito.mock(ServletUtils.class);
+ private static final ComponentsUtils componentsUtils = Mockito.mock(ComponentsUtils.class);
+ private static final ResourceImportManager resourceImportManager = Mockito.mock(ResourceImportManager.class);
+ private static final ResourceBusinessLogic resourceBusinessLogic = Mockito.mock(ResourceBusinessLogic.class);
+ private static final ServiceBusinessLogic serviceBusinessLogic = Mockito.mock(ServiceBusinessLogic.class);
+ private static final ElementBusinessLogic elementBusinessLogic = Mockito.mock(ElementBusinessLogic.class);
+ private static final Resource resource = Mockito.mock(Resource.class);
+ private static final CategoryDefinition categoryDefinition = Mockito.mock(CategoryDefinition.class);
+ private static final SubCategoryDefinition subCategoryDefinition = Mockito.mock(SubCategoryDefinition.class);
+ private static final AssetMetadataConverter assetMetadataConverter = Mockito.mock(AssetMetadataConverter.class);
+ private static final ResourceAssetMetadata resourceAssetMetadata = new ResourceAssetMetadata();
+ private static final UserBusinessLogic userBusinessLogic = Mockito.mock(UserBusinessLogic.class);
+ private static final ComponentInstanceBusinessLogic componentInstanceBusinessLogic = Mockito.mock(ComponentInstanceBusinessLogic.class);
+ private static final LifecycleBusinessLogic lifecycleBusinessLogic = Mockito.mock(LifecycleBusinessLogic.class);
@@ -203,8 +204,9 @@ public class AssetsDataServletTest extends JerseyTest {
bind(assetMetadataConverter).to(AssetMetadataConverter.class);
bind(lifecycleBusinessLogic).to(LifecycleBusinessLogic.class);
bind(resourceBusinessLogic).to(ResourceBusinessLogic.class);
+ bind(serviceBusinessLogic).to(ServiceBusinessLogic.class);
}
})
.property("contextConfig", context);
}
-} \ No newline at end of file
+}
diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/impl/ComponentsUtilsTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/impl/ComponentsUtilsTest.java
index b76ac2e70f..a4c8a3dd7d 100644
--- a/catalog-be/src/test/java/org/openecomp/sdc/be/impl/ComponentsUtilsTest.java
+++ b/catalog-be/src/test/java/org/openecomp/sdc/be/impl/ComponentsUtilsTest.java
@@ -432,11 +432,7 @@ public class ComponentsUtilsTest {
testSubject.auditComponent(responseFormat, modifier, component, actionEnum, prevComponent,info);
}
-
-
-
-
@Test
public void testAuditComponent_1() throws Exception {
ComponentsUtils testSubject;
@@ -452,14 +448,6 @@ public class ComponentsUtilsTest {
testSubject.auditComponent(responseFormat, modifier, component, actionEnum, type, prevComponent);
}
-
-
-
-
-
-
-
-
@Test
public void testValidateStringNotEmpty() throws Exception {
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java
index da5eab8747..3e2b95b129 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java
@@ -53,6 +53,7 @@ public enum AuditingActionEnum {
ARTIFACT_DELETE_BY_API("ArtifactDeleteByAPI", AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
DOWNLOAD_ARTIFACT("DownloadArtifact",AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
CREATE_RESOURCE_BY_API("CreateResourceByAPI", AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
+ CREATE_SERVICE_BY_API("CreateServiceByAPI", AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
CHANGE_LIFECYCLE_BY_API("ChangeLifecycleByAPI", AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
ACTIVATE_SERVICE_BY_API("ActivateServiceByAPI", AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE),
diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnum.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnum.java
new file mode 100644
index 0000000000..22ef7f3031
--- /dev/null
+++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnum.java
@@ -0,0 +1,110 @@
+/*-
+ * Copyright (C) 2019 Telstra 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.
+ */
+
+package org.openecomp.sdc.be.datatypes.enums;
+
+/**
+ * Category Type Enum
+ * Any service category to be supported by SDC Ext API can be added here
+ *
+ * @author atifhusain
+ */
+public enum ExternalCategoryTypeEnum {
+
+ PARTNER_DOMAIN_SERVICE("Partner Domain Service", true);
+
+ private String value;
+ private boolean isAtomicType;
+
+ ExternalCategoryTypeEnum(String value, boolean isAtomicType) {
+ this.value = value;
+ this.isAtomicType = isAtomicType;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public boolean isAtomicType() {
+ return isAtomicType;
+ }
+
+ public static ExternalCategoryTypeEnum getType(String type) {
+ for (ExternalCategoryTypeEnum e : ExternalCategoryTypeEnum.values()) {
+ if (e.name().equals(type)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ public static ExternalCategoryTypeEnum getTypeByName(String type) {
+ for (ExternalCategoryTypeEnum e : ExternalCategoryTypeEnum.values()) {
+ if (e.getValue().equalsIgnoreCase(type)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns CategoryTypeEnum matching to received String ignore case
+ *
+ * @param type
+ * @return
+ */
+ public static ExternalCategoryTypeEnum getTypeIgnoreCase(String type) {
+ for (ExternalCategoryTypeEnum e : ExternalCategoryTypeEnum.values()) {
+ if (e.getValue().equalsIgnoreCase(type)) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Checks if enum exist with given type
+ *
+ * @param type
+ * @return
+ */
+ public static boolean containsName(String type) {
+
+ for (ExternalCategoryTypeEnum e : ExternalCategoryTypeEnum.values()) {
+ if (e.getValue().equals(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if enum exist with given type ignore case
+ *
+ * @param type
+ * @return
+ */
+ public static boolean containsIgnoreCase(String type) {
+
+ for (ExternalCategoryTypeEnum e : ExternalCategoryTypeEnum.values()) {
+ if (e.getValue().equalsIgnoreCase(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
+
diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnumTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnumTest.java
new file mode 100644
index 0000000000..d1e5861344
--- /dev/null
+++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/enums/ExternalCategoryTypeEnumTest.java
@@ -0,0 +1,129 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2019 Telstra 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.openecomp.sdc.be.datatypes.enums;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ExternalCategoryTypeEnumTest {
+
+ private static final String PARTNER_DOMAIN_SERVICE_UPPER = "Partner Domain Service";
+ private static final String PARTNER_DOMAIN_SERVICE_LOWER = "partner domain service";
+ private ExternalCategoryTypeEnum createTestSubject() {
+ return ExternalCategoryTypeEnum.PARTNER_DOMAIN_SERVICE;
+ }
+
+ @Test
+ public void testGetValue() {
+ ExternalCategoryTypeEnum testSubject;
+ String result;
+
+ // default test
+ testSubject = createTestSubject();
+ result = testSubject.getValue();
+ Assert.assertSame(result, ExternalCategoryTypeEnum.PARTNER_DOMAIN_SERVICE.getValue());
+ }
+
+ @Test
+ public void testIsAtomicType() {
+ ExternalCategoryTypeEnum testSubject;
+ boolean result;
+
+ // default test
+ testSubject = createTestSubject();
+ result = testSubject.isAtomicType();
+ Assert.assertSame(result,true);
+ }
+
+ @Test
+ public void testGetInvalidType() {
+ String type = "Invalid Service";
+ ExternalCategoryTypeEnum result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.getType(type);
+ Assert.assertSame(result, null);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void testGetValidType() {
+ String type = "PARTNER_DOMAIN_SERVICE";
+ ExternalCategoryTypeEnum result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.getType(type);
+ Assert.assertSame(result, ExternalCategoryTypeEnum.PARTNER_DOMAIN_SERVICE);
+
+ }
+
+ @Test
+ public void testGetTypeByName() {
+ String type = "";
+ ExternalCategoryTypeEnum result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.getType(type);
+ Assert.assertSame(result, null);
+ result = ExternalCategoryTypeEnum.getTypeByName(ExternalCategoryTypeEnumTest.PARTNER_DOMAIN_SERVICE_UPPER);
+ Assert.assertSame(result, ExternalCategoryTypeEnum.PARTNER_DOMAIN_SERVICE);
+
+ }
+
+ @Test
+ public void testGetTypeIgnoreCase() {
+ String type = "";
+ ExternalCategoryTypeEnum result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.getTypeIgnoreCase(type);
+ Assert.assertSame(result, null);
+ result = ExternalCategoryTypeEnum.getTypeIgnoreCase(ExternalCategoryTypeEnumTest.PARTNER_DOMAIN_SERVICE_LOWER);
+ Assert.assertSame(result,ExternalCategoryTypeEnum.PARTNER_DOMAIN_SERVICE );
+ }
+
+ @Test
+ public void testContainsName() {
+ String type = "";
+ boolean result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.containsName(type);
+ Assert.assertSame(result,false);
+ result = ExternalCategoryTypeEnum.containsName(ExternalCategoryTypeEnumTest.PARTNER_DOMAIN_SERVICE_LOWER);
+ Assert.assertSame(result,false);
+ }
+
+ @Test
+ public void testContainsIgnoreCase() {
+ String type = "";
+ boolean result;
+
+ // default test
+ result = ExternalCategoryTypeEnum.containsIgnoreCase(type);
+ Assert.assertSame(result,false);
+ result = ExternalCategoryTypeEnum.containsIgnoreCase(ExternalCategoryTypeEnumTest.PARTNER_DOMAIN_SERVICE_LOWER);
+ Assert.assertSame(result,true);
+ result = ExternalCategoryTypeEnum.containsIgnoreCase(ExternalCategoryTypeEnumTest.PARTNER_DOMAIN_SERVICE_UPPER);
+ Assert.assertSame(result,true);
+ }
+}
+
diff --git a/docs/swagger/swagger.html b/docs/swagger/swagger.html
index cb09cfb40b..ceee720cc1 100644
--- a/docs/swagger/swagger.html
+++ b/docs/swagger/swagger.html
@@ -442,7 +442,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<li><a href="#_tags_7">2.6.6. Tags</a></li>
</ul>
</li>
-<li><a href="#_createresourceexternal">2.7. creates a resource</a></li>
+<li><a href="#_createcomponentexternal">2.7. creates a resource or service</a></li>
<li>
<ul class="sectlevel3">
<li><a href="#_description_7">2.7.1. Description</a></li>
@@ -2382,7 +2382,7 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</div>
</div>
<div class="sect2">
-<h3 id="_createresourceexternal"><a class="anchor" href="#_createresourceexternal"></a>2.7. creates a resource</h3>
+<h3 id="_createcomponentexternal"><a class="anchor" href="#_createcomponentexternal"></a>2.7. creates a resource or service</h3>
<div class="literalblock">
<div class="content">
<pre>POST /v1/catalog/{assetType}</pre>
diff --git a/docs/swagger/swagger.json b/docs/swagger/swagger.json
index 766a3c757a..726f76d754 100644
--- a/docs/swagger/swagger.json
+++ b/docs/swagger/swagger.json
@@ -1785,9 +1785,9 @@
"tags": [
"CRUD External Servlet"
],
- "summary": "creates a resource",
- "description": "Creates a resource",
- "operationId": "createResourceExternal",
+ "summary": "creates a resource or service",
+ "description": "Creates a resource or service",
+ "operationId": "createComponentExternal",
"consumes": [
"application/json"
],